Free Candies

Free Candies 

题链接 https://vjudge.net/contest/241993#problem/B

题意:有四堆糖果,每堆糖果有n个,有一个篮子,最多只能装5个糖果,每次从任意一堆堆顶拿走一个糖果,如果篮子里有俩个            相同的糖果,那么可以被自己收下,看看最多能收下几对糖果

题解:这道题用记忆化搜索,定义一个dp的四维数组代表每堆糖果分别被拿了a,b,c,d个糖果时最多拿走的糖果对数,定义                   d【4】数组,d【0】d【1】d【2】d【3】分别代表每堆糖果已经被拿走的糖果数,定义book数组标记糖果,如果某个                糖果被 放进篮子里,那么标记为1。

代码:

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int dp[100][100][100][100];
int s[4][100],book[100],h[4],n;
int dfs(int x)
{
    if(dp[h[0]][h[1]][h[2]][h[3]]!=-1)     //该状态被搜过 ,返回
        return dp[h[0]][h[1]][h[2]][h[3]];
    if(x==5)                              //篮子里的五个糖果不一样,退出
        return dp[h[0]][h[1]][h[2]][h[3]]=0;
    int sum=0;                 
    for(int i=0;i<4;i++)
    {
        if(h[i]==n)                      //这堆已被拿完
            continue;
        int k=s[i][h[i]]; 
        h[i]++;
        if(book[k])                    //表示篮子里有一样的
        {
            book[k]=0;
            sum=max(sum,dfs(x-1)+1);    //拿出,对数加1
            book[k]=1;
        }
        else                           //篮子里没有一样的
        {
            book[k]=1;
            sum=max(sum,dfs(x+1));      
            book[k]=0;
        }
        h[i]--;               //回溯
    }
    return dp[h[0]][h[1]][h[2]][h[3]]=sum;
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
    	memset(h,0,sizeof(h));
        memset(dp,-1,sizeof(dp));
        memset(book,0,sizeof(book));
        int i,j;
        for( i=0;i<n;i++)
            for( j=0;j<4;j++)
                scanf("%d",&s[j][i]);
       
        printf("%d\n",dfs(0));
    }
}

猜你喜欢

转载自blog.csdn.net/zhengde152/article/details/81275247