题意:有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,如果篮子里有两个相同的糖果,那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走多少对糖果。糖果种类最多20种.
#include<stdio.h>
#include<queue>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<assert.h>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<fstream>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define debug printf("---------------\n");
using namespace std;
int pile[4][45];
int dp[45][45][45][45];
int n,top[4];
int dfs(int coun,bool hax[])
{
if(dp[top[0]][top[1]][top[2]][top[3]]!=-1)
{
return dp[top[0]][top[1]][top[2]][top[3]];
}
if(coun==5)//篮子装满
{
return dp[top[0]][top[1]][top[2]][top[3]]=0;
}
int ans=0;
for(int i=0;i<4;i++)
{
if(top[i]==n)//这个糖果堆已拿完
{
continue;
}
int color=pile[i][top[i]];
top[i]++;
if(hax[color])//如果有相同颜色,则取出
{
hax[color]=false;
ans=max(ans,dfs(coun-1,hax)+1);
hax[color]=true;
}
else//没有则直接放入,深搜
{
hax[color]=true;
ans=max(ans,dfs(coun+1,hax));
hax[color]=false;
}
top[i]--;
}
return dp[top[0]][top[1]][top[2]][top[3]]=ans;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<4;j++)
{
scanf("%d",&pile[j][i]);
}
}
bool hax[25];
memset(dp,-1,sizeof(dp));
memset(hax,false,sizeof(hax));
top[0]=top[1]=top[2]=top[3]=0;
printf("%d\n",dfs(0,hax));
}
return 0;
}