【UVA10118】Free Candies(记忆化搜索)

问题描述】

有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 }
View Code
原文地址:https://www.cnblogs.com/qq-1585047819/p/11802033.html