UVa 10118 记忆化搜索 Free Candies

假设在当前状态我们第i堆糖果分别取了cnt[i]个,那么篮子里以及口袋里糖果的个数都是可以确定下来的。

所以就可以使用记忆化搜索。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 45;
 7 const int maxm = 4;
 8 
 9 int n;
10 
11 int candy[maxn][maxm];
12 int d[maxn][maxn][maxn][maxn];
13 
14 struct State
15 {
16     int tot;        //篮子里糖果的数量
17     int cnt[4];     //第i堆糖果取了cnt[i]个
18     int kind[21];   //篮子里第i中糖果有ind[i]个
19 };
20 
21 int dp(State s)
22 {
23     int& ans = d[s.cnt[0]][s.cnt[1]][s.cnt[2]][s.cnt[3]];
24     if(ans >= 0) return ans;
25     if(s.tot == 5) return ans = 0;
26 
27     ans = 0;
28     for(int i = 0; i < 4; i++)
29     {
30         if(s.cnt[i] == n) continue;
31         int color = candy[s.cnt[i]][i];
32         s.cnt[i]++;
33         if(s.kind[color])
34         {
35             s.tot--;
36             s.kind[color] = 0;
37             ans = max(ans, dp(s) + 1);
38             s.tot++;
39             s.kind[color] = 1;
40 
41         }
42         else
43         {
44             s.tot++;
45             s.kind[color] = 1;
46             ans = max(ans, dp(s));
47             s.tot--;
48             s.kind[color] = 0;
49         }
50         s.cnt[i]--;
51     }
52     return ans;
53 }
54 
55 int main()
56 {
57     while(scanf("%d", &n) == 1 && n)
58     {
59         for(int i = 0; i < n; i++)
60             for(int j = 0; j < 4; j++) scanf("%d", &candy[i][j]);
61 
62         State s;
63         s.tot = 0;
64         for(int i = 0; i < 4; i++) s.cnt[i] = 0;
65         for(int i = 1; i <= 20; i++) s.kind[i] = 0;
66         memset(d, -1, sizeof(d));
67         printf("%d
", dp(s));
68     }
69 
70     return 0;
71 }
代码君
原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4777375.html