问题描述】
有4根竖直的管子,每个管子里有n颗糖果叠成一堆,有一个篮子,最多可以放5颗糖果。每次可以取走任意一个管子的最上方的一颗糖果放到篮子里,若篮子里有两颗糖的颜色相同,可以将这一对糖果放进口袋。求最多可以放多少对糖果到口袋里。
【输入格式】
输入有若干组(不超过10组)测试数据,对于每组测试数据:
第一行一个整数n(1≤n≤40),表示每根管子有多少糖果,接下来n行,每行4个整数,第i行第j列表示第j根管子的第i颗糖果的颜色。糖果的颜色不超过20种,分别编号为1到n。
输入最后一行,用一个0表示结束。
【输出格式】
输出共若干行,对每组测试数据依次输出答案,各占一行。
【输入样例1】
5
1 2 3 4
1 5 6 7
2 3 3 3
4 9 8 6
8 7 2 1
1
1 2 3 4
3
1 2 3 4
5 6 7 8
1 2 3 4
0
【输出样例1】
8
0
3

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 6 using namespace std; 7 int n; 8 int brr[5]; 9 int dp[45][45][45][45]; //每个管子拿了几个糖果时口袋的糖果数量 10 int arr[5][45]; 11 12 int dfs(int state,int nums){ //篮子中的状态和数量 13 int &ans=dp[brr[1]][brr[2]][brr[3]][brr[4]]; 14 if(ans!=-1) return ans; 15 else{ 16 int sum; 17 for(int i=1;i<=4;i++){ 18 sum=0; 19 ++brr[i]; 20 if(brr[i]<=n){ 21 int temp=1<<arr[i][brr[i]]; 22 if(temp&state){ //篮子里面有这种状态 23 sum=dfs((~temp)&state,nums-1)+1; 24 } 25 else{ //篮子里面没有这种状态 26 if(nums<4){ //不能等于4 如果等于4 放入这个就是5颗了但是这颗和之前的状态都不同所以肯定时不行的 27 sum=dfs(temp|state,nums+1); 28 } 29 } 30 } 31 --brr[i]; //还原 32 ans=max(ans,sum); 33 } 34 return ans; 35 } 36 } 37 38 39 40 int main(){ 41 ios::sync_with_stdio(false); 42 while(cin>>n,n){ 43 for(int i=1;i<=n;i++){ 44 for(int j=1;j<=4;j++){ 45 cin>>arr[j][i]; 46 } 47 } 48 memset(dp,-1,sizeof(dp)); 49 memset(brr,0,sizeof(brr)); 50 cout << dfs(0,0) << endl; 51 } 52 return 0; 53 }