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 */
康复训练中~欢迎交流!