1. 程式人生 > >uva 10118 Free Candies

uva 10118 Free Candies

代碼 ans mem 繼續 con algo str 並且 IE

題意:

有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 */

uva 10118 Free Candies