题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1514
题目意思:有4堆糖果,每堆糖果有n个,从上到下排好,取糖果只能从上往下取,取完的糖果放在篮子里,篮子里最多放5个,如果篮子里有两个颜色相同的糖果则可以取走放进口袋里,问最多能取走多少对糖果放进口袋。n<=40, 糖果颜色最多20种。
这题是抄这个人滴:http://fudq.blog.163.com/blog/static/1913502382014239225290/
有些地方看得不太懂,本来想搜状态压缩DP来体会下的,阴差阳错、迷迷糊糊找到了这题= =.......可能水平不太够啦,先留着吧.......能理解到的我都写注释了,不能理解的打了个“?”
只能说,DP好抽象啊,泪 >_< ,慢慢来吧,继续努力!!!
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <set> 6 using namespace std; 7 8 const int candy_num = 40 + 5; 9 const int basket_num = 5 + 2; 10 11 // dp[i][j][k][l]: 四个糖堆分别拿走了几个 12 // 第1个pile被取走i个,第2个pile被取走j个,第3个pile被取走k个,第4个pile被取走l个时pocket能装入的candy数 13 // h[i]:记录第i个糖堆被取走了多少糖果 14 int dp[candy_num][candy_num][candy_num][candy_num]; 15 int h[basket_num], f[candy_num][basket_num]; 16 int ans, n; 17 18 set<int> S; 19 set<int> ::iterator it; 20 21 int check(int a) 22 { 23 it = S.find(a); 24 if (it != S.end()) // basket里面有颜色跟当前颜色(a)相同的糖果,从basket里拿出 25 { 26 S.erase(a); 27 return 1; 28 } 29 S.insert(a); // basket中没有a这种颜色,放入basket中 30 return 0; 31 } 32 33 int dfs(int tmp) 34 { 35 if (dp[h[0]][h[1]][h[2]][h[3]] != -1) // 这个状态搜过 36 return dp[h[0]][h[1]][h[2]][h[3]]; 37 int tt = 0; 38 for (int i = 0; i < 4; i++) // 从四个basket中拿糖果 39 { 40 if (h[i] < n && S.size() < 5) 41 { 42 int t = check(f[h[i]][i]); 43 if (S.size() < 5) 44 { 45 h[i]++; // 第i个pile里被取走一个candy 46 tt = max(tt, dfs(tmp+t)); // ? 47 h[i]--; 48 } 49 tt = max(tt, tmp+t); // ? 50 if (t == 1) 51 S.insert(f[h[i]][i]); 52 else 53 S.erase(f[h[i]][i]); 54 } 55 } 56 return dp[h[0]][h[1]][h[2]][h[3]] = tt; 57 } 58 59 int main() 60 { 61 while (scanf("%d", &n) != EOF && n) 62 { 63 for (int i = 0; i < n; i++) 64 { 65 for (int j = 0; j < 4; j++) 66 scanf("%d", &f[i][j]); 67 } 68 /* for (int i = 0; i < n; i++) 69 { 70 for (int j = 0; j < 4; j++) 71 printf("f[%d][%d] = %d ", i, j, f[i][j]); 72 } 73 */ 74 ans = 0; 75 h[0] = h[1] = h[2] = h[3] = 0; 76 memset(dp, -1, sizeof(dp)); 77 printf("%d ", dfs(0)); 78 // printf("dp[%d][%d][%d][%d] = %d ", h[0], h[1], h[2], h[3], dp[h[0]][h[1]][h[2]][h[3]]); 79 } 80 return 0; 81 }