uva 10118 Free Candies

题意:

有4堆糖,每堆有n个,每次从某一堆的堆顶拿一个放进篮子里,如果篮子里有2个颜色相同的糖果,那么就可以放进袋子里。

当篮子里有5个糖果并且没有相同颜色的糖果时,这个时候就不能再拿了。

问最多可以拿多少对颜色相同的糖果。

思路:

记忆化搜索。

设dp[x][y][z][w]表示第一堆拿走了x个,第二堆拿走了y个,第三堆拿走了z,第四堆拿走了w个时,可以取得的最大对数。

篮子里的糖果,因为最多只有20种颜色,所以可以状态压缩表示,当大于等于5个的时候,就无法再继续了。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 20;
 6 int n;
 7 int a[45][5];
 8 int dp[45][45][45][45];
 9 int dfs(int x,int y,int z,int w,int sta)
10 {
11     int &ans = dp[x][y][z][w];
12     if (~ans) return ans;
13     int cnt = 0;
14     for (int i = 0;i < 20;i++)
15     {
16         if (sta & (1<<i)) cnt++;
17     }
18     if (cnt >= 5) return ans = 0;
19     if (x < n)
20     {
21         int tmp;
22         if (sta & (1 << a[x+1][1]-1))
23         {
24             tmp = dfs(x+1,y,z,w,sta ^ (1 << a[x+1][1]-1)) + 1;
25         }
26         else
27         {
28             //printf("hh\n");
29             tmp = dfs(x+1,y,z,w,sta ^ (1 << a[x+1][1]-1));
30         }
31         ans = max(ans,tmp);
32     }
33     if (y < n)
34     {
35         int tmp;
36         if (sta & (1 << a[y+1][2]-1))
37         {
38             tmp = dfs(x,y+1,z,w,sta ^ (1 << a[y+1][2]-1)) + 1;
39         }
40         else
41         {
42             tmp = dfs(x,y+1,z,w,sta ^ (1 << a[y+1][2]-1));
43         }
44         ans = max(ans,tmp);
45     }
46     if (z < n)
47     {
48         int tmp;
49         if (sta & (1 << a[z+1][3]-1))
50         {
51             tmp = dfs(x,y,z+1,w,sta ^ (1 << a[z+1][3]-1)) + 1;
52         }
53         else
54         {
55             tmp = dfs(x,y,z+1,w,sta ^ (1 << a[z+1][3]-1));
56         }
57         ans = max(tmp,ans);
58     }
59     if (w < n)
60     {
61         int tmp;
62         if (sta & (1 << a[w+1][4]-1))
63         {
64             tmp = dfs(x,y,z,w+1,sta ^ (1 << a[w+1][4]-1)) + 1;
65         }
66         else
67         {
68             tmp = dfs(x,y,z,w+1,sta ^ (1 << a[w+1][4]-1));
69         }
70         ans = max(ans,tmp);
71     }
72     if (ans == -1) return ans = 0;
73     
74     return ans;
75 }
76 int main()
77 {
78     while (scanf("%d",&n) != EOF && n)
79     {
80         memset(dp,-1,sizeof(dp));
81         for (int i = 1;i <= n;i++)
82         {
83             for (int j = 1;j <= 4;j++) scanf("%d",&a[i][j]);
84         }
85         int ans = dfs(0,0,0,0,0);
86         printf("%d\n",ans);
87     }
88     return 0;
89 }
90 /*
91 3 1 2 3 4 5 6 7 8 1 2 3 4
92 */

 

posted @ 2018-05-05 23:14  qrfkickit  阅读(140)  评论(0编辑  收藏  举报