标签:des style blog io color ar os java for
3 4 3 2 2 3 2 1 3 2 1 2 3 2 3 1 3 2 2 3 2 3 1 3 1 2 3 0 0 0
3 -3HintFor the first case, in turn 2, bob has to choose at least one bag, so that Alice will make a Magic Stone at the end of turn 3, thus get turn 4 and get all the three Magic Stones.
题意:有b个袋子,袋子中装有一些不同颜色的宝石,两个人轮流一个袋子把宝石放入cooker,若有s个宝石颜色相同,这个人得到一分,这 s个宝石消失;且某次得到分数,则可以再取一次。求先手和后手的最大差值。
解题思路:因为最多只有21个袋子,可以考虑状态压缩,且给定袋子宝石数量,可知两个人的总得分是固定的。对于每个状态dp[s]表示当前状态下先手能获得的最大分数,然后,枚举该状态下先手可取的每个袋子作为第一次选择,若选择该袋子能得到分数sum,则先手再取一次,dp[s]=sum+dfs(s^(1<<i),left-sum,c);否则,先手得到分数为当前剩余分数减去后手能得到的分数dp[s]=left-dfs(s^(1<<i),left,c);
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
using namespace std;
#define LL __int64
#define N 25
const int inf=-0x1f1f1f1f;
int g,b,s;
int box[25][10];
int dp[1<<21];
int dfs(int S,int left,int c[])
{
if(dp[S]!=inf)
return dp[S];
if(S==0||left==0)
return 0;
int ans=0,i;
int a[10];
for(i=0;i<b;i++)
{
int sum=0;
if(S&(1<<i))
{
int tmp=S^(1<<i),cnt;
for(int j=1;j<=g;j++)
{
a[j]=c[j]+box[i][j];
sum+=a[j]/s;
a[j]%=s;
}
if(sum)
cnt=sum+dfs(tmp,left-sum,a);
else
cnt=left-dfs(tmp,left,a);
ans=max(ans,cnt);
}
}
return dp[S]=ans;
}
int main()
{
int i,x,m;
int num[10];
while(scanf("%d%d%d",&g,&b,&s),g||b||s)
{
memset(box,0,sizeof(box));
memset(num,0,sizeof(num));
for(i=0;i<b;i++)
{
scanf("%d",&m);
while(m--)
{
scanf("%d",&x);
box[i][x]++;
num[x]++;
}
}
int sum=0;
for(i=1;i<=g;i++)
sum+=num[i]/s;
for(i=0;i<(1<<b);i++)
dp[i]=inf;
int c[10];
memset(c,0,sizeof(c));
int ans=dfs((1<<b)-1,sum,c);
printf("%d\n",ans*2-sum);
}
return 0;
}
hdu 4778 Gems Fight!(状态压缩+博弈+记忆化)
标签:des style blog io color ar os java for
原文地址:http://blog.csdn.net/u011721440/article/details/40826571