hdu 1514 记忆化搜索

题意是给4堆(堆的高度小于等于40)有颜色(颜色的种类小于等于20)的物品,你有一个篮子最多能装5件物品,每次从这4堆物品里面
任取一件物品放进篮子里,但是取每堆物品时,必须先取上面的物品,才能取下面的物品,如果发现篮子里
的两种物品的颜色一样,那么把这两种物品拿出来,问最后最多能拿出多少对物品?;
解题思路:记忆化搜索+dp+状态压缩;
因为40×40×40×40不会太大,所以可以用dp[x[1]][x[2]][x[3]][x[4]]记录搜索的状态;
dp[x[1]][x[2]][x[3]][x[4]]记录4堆分别从x[1],x[2],x[3],x[4]处往下取所获得的最大值;
因为颜色种类最多20种,可以对篮子里的物品颜色用每个位来存储,所以就用到了位状态压缩;
Sample Input
5
1 2 3 4
1 5 6 7
2 3 3 3
4 9 8 6
8 7 2 1
Sample Output
8

 

 

这题少说也拍过5遍了,好题啊

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 #define cl(a) memset(a,0,sizeof(a))
13 #define ts printf("*****\n");
14 const int MAXN=1005;
15 int n,m,tt;
16 int dp[45][45][45][45];
17 int c[45][5];
18 int x[5];       //x[i]表示第i堆的状态,并不是当前状态,而是取走的状态
19 int dfs(int b,int num)
20 {
21     if(dp[x[1]][x[2]][x[3]][x[4]]!=-1)  return dp[x[1]][x[2]][x[3]][x[4]];
22     int maxs=0,sum=0;
23     for(int i=1;i<=4;i++)
24     {
25         x[i]++;
26         if(x[i]<=n)
27         {
28             int bit=1<<(c[x[i]][i]);
29             if(b&bit)
30             {
31                 sum=dfs(b&(~bit),num-1)+1;
32             }
33             else if(num<4)
34             {
35                 sum=dfs(b|bit,num+1);
36             }
37         }
38         maxs=max(maxs,sum);
39         x[i]--;
40     }
41     return dp[x[1]][x[2]][x[3]][x[4]]=maxs;
42 }
43 int main()
44 {
45     int i,j,k;
46     #ifndef ONLINE_JUDGE
47     freopen("1.in","r",stdin);
48     #endif
49     while(scanf("%d",&n)!=EOF&&n!=0)
50     {
51         for(i=1;i<=n;i++)
52         {
53             for(j=1;j<=4;j++)
54                 scanf("%d",&c[i][j]);
55         }
56         memset(dp,-1,sizeof(dp));
57         x[1]=x[2]=x[3]=x[4]=0;
58         int ans=dfs(0,0);
59         printf("%d\n",ans);
60     }
61 }

 

posted @ 2015-04-25 11:15  miao_a_miao  阅读(190)  评论(0编辑  收藏  举报