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 }

 

你可能感兴趣的:(HDU)