记忆化搜索dp(UVa - 10118 Free Candies)

来源:互联网 发布:淘宝开店费用多少 编辑:程序博客网 时间:2024/06/05 20:23

题意:有4堆糖果,每堆有n个,有一个篮子,最多装5个糖果,我们每次拿某一堆糖果最上面的一个,如果篮子里有两个相同的糖果,那么就可以把这一对糖果放进自己的口袋里,问最多能拿走多少对糖果。

思路:dp[a][b][c][d]表示对应堆的糖果拿走a,b,c,d个后,口袋里最多有多少糖果,对于篮子装满的情况dp值为0,记忆话搜索

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=41;int dp[maxn][maxn][maxn][maxn];int candy[4][maxn];int top[4];int H;int basket[25];int DP(int cnt){    int a=top[0],b=top[1],c=top[2],d=top[3];    if(cnt>=5)return dp[a][b][c][d]=0;    if(dp[a][b][c][d]!=-1)return dp[a][b][c][d];    int &ans=dp[a][b][c][d];    ans=0;    for(int i=0;i<4;i++)    {        if(top[i]<H)        {            int &tmp=basket[candy[i][top[i]]];            top[i]++;            if(tmp)            {                tmp=0;                ans=max(ans,DP(cnt-1)+1);                tmp=1;            }            else            {                tmp=1;                ans=max(DP(cnt+1),ans);                tmp=0;            }            top[i]--;        }    }    return ans;}int main(){    while(scanf("%d",&H)!=EOF,H)    {        for(int j=0;j<H;j++)            for(int i=0;i<4;i++)scanf("%d",&candy[i][j]);        memset(dp,-1,sizeof(dp));        memset(top,0,sizeof(top));        memset(basket,0,sizeof(basket));        printf("%d\n",DP(0));    }    return 0;}




0 0