题意:有四根管道,每根里面有n颗糖,每次只能从管道的最上面拿糖进篮子里。如果篮子里面有两颗颜色一样的糖(数值大小一样),那么Bob可以将这两颗糖揣进自己的口袋里,如果篮子里的糖数为5颗,就结束。问Bob最多能拿到几颗糖
思路:将每根管道拿出的糖数num[1],num[2],num[3],num[4]作为一种状态,求解该状态下还能拿多少颗糖
留了一个疑惑在返回和输出的地方_(:з」∠)_
#include<iostream>
#include<stdlib.h>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=50;
int in[25]; //颜色i是否在篮子里
int dp[N][N][N][N]; //四个管道分别选了前i,j,k,l个糖时还能取的腰包里最大糖数
int a[N][4];
int top[4]; //top[i]记录第i个管道在选第几颗糖
int n;
int dfs(int cnt) //求每个状态下还能选的糖的最大值 cnt表示篮子里面有cnt颗糖
{
int &ans=dp[top[0]][top[1]][top[2]][top[3]];
if(ans!=-1) return ans;
if(cnt==5) return ans=0;
ans=0;
for(int i=0;i<4;++i)
{
if(top[i]==n) continue;
int color=a[top[i]++][i];
if(in[color])
{
in[color]=0; //已经有这个颜色了,那么我要把它拿出来
ans=max(ans,dfs(cnt-1)+1);//因为拿出来了,所以篮子里糖数减少了1
in[color]=1; //回溯
}
else
{
in[color]=1;
ans=max(ans,dfs(cnt+1));//放进去了一颗,篮子里糖数增加1
in[color]=0;
}
top[i]--;
}
return dp[top[0]][top[1]][top[2]][top[3]]=ans; //为啥我直接返回ans,输出答案的时候输出dp[0][0][0][0]就不对??
}
int main()
{
while(cin>>n)
{
if(!n) break;
memset(in,0,sizeof(in));
memset(dp,-1,sizeof(dp)); //初始化为该状态未计算过
memset(top,0,sizeof(top));
for(int i=0;i<n;++i)
for(int j=0;j<4;++j)
{
cin>>a[i][j];
}
cout<<dfs(0)<<endl;
}
}