HDU 4778 Gems Fight! (博弈+状压DP)

来源:互联网 发布:java web 界面模板 编辑:程序博客网 时间:2024/05/16 10:52
Problem Description
  Alice and Bob are playing "Gems Fight!":
  There are Gems of G different colors , packed in B bags. Each bag has several Gems. G different colors are numbered from color 1 to color G.
  Alice and Bob take turns to pick one bag and collect all the Gems inside. A bag cannot be picked twice. The Gems collected are stored in a shared cooker.
  After a player ,we name it as X, put Gems into the cooker, if there are S Gems which are the same color in the cooker, they will be melted into one Magic Stone. This reaction will go on and more than one Magic Stone may be produced, until no S Gems of the same color remained in that cooker. Then X owns those new Magic Stones. When X gets one or more new Magic Stones, he/she will also get a bonus turn. If X gets Magic Stone in a bonus turn, he will get another bonus turn. In short,a player may get multiple bonus turns continuously.
  There will be B turns in total. The goal of "Gems Fight!" is to get as more Magic Stones than the opponent as possible.
  Now Alice gets the first turn, and she wants to know, if both of them act the optimal way, what will be the difference between the number of her Magic Stones and the number of Bob's Magic Stones at the end of the game.
 

Input
  There are several cases(<=20).
  In each case, there are three integers at the first line: G, B, and S. Their meanings are mentioned above.
  Then B lines follow. Each line describes a bag in the following format:
  
  n c1 c2 ... cn
  
  It means that there are n Gems in the bag and their colors are color c1,color c2...and color cn respectively.
   0<=B<=21, 0<=G<=8, 0<n<=10, S < 20.
  There may be extra blank lines between cases. You can get more information from the sample input.
  The input ends with G = 0, B = 0 and S = 0.
 

Output
  One line for each case: the amount of Alice's Magic stones minus the amount of Bob's Magic Stones.
 

Sample Input
3 4 32 2 32 1 32 1 23 2 3 13 2 23 2 3 13 1 2 30 0 0
 

Sample Output
3-3
Hint
  For 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.
 

Source
2013 Asia Hangzhou Regional Contest
 
推荐阅读博客:点击打开链接

此题确实又是刷到的一道好题,大神们都写了很多很详细的博客了,我就不用再多废话了,写一篇博客当作笔记,以便以后再回来看看,复习复习。

代码实现:
#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<cstdio>#define ll long long#define mset(a,x) memset(a,x,sizeof(a))using namespace std;const double PI=acos(-1);const int inf=0x3f3f3f3f;const double esp=1e-6;const int maxn=250005;const int mod=1e9+7;int dir[4][2]={0,1,1,0,0,-1,-1,0};ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}ll lcm(ll a,ll b){return a/gcd(a,b)*b;}ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}int dp[1<<22],map[25][25],now[25],temp[25];//map记录,now储存当前状态下已经取得的各颜色宝石的数量,temp储存拿走一袋后宝石的数量 int main(){int G,B,S,i,j,k,x;while(cin>>G>>B>>S){if(!G&&!B&&!S)break;mset(map,0);mset(dp,0);for(i=0;i<B;i++)                    //存入数组 {cin>>x;for(j=0;j<x;j++){cin>>k;map[i][k]++;}}int maxx=(1<<B)-1;                 //得到当前状态代表的最大值 for(i=1;i<=maxx;i++)               //枚举每一种状态 {dp[i]=-inf;                    //由于dp可能是负数所以赋值为-inf mset(now,0);for(j=0;j<B;j++)               //枚举每一袋 {if((i&(1<<j))==0)          //把每一袋代表的1都去掉,即拿走每一袋 for(k=1;k<=G;k++)          //枚举每一种宝石 {now[k]+=map[j][k];     //求的得到的当前宝石的数量 while(now[k]>=S)       //超过s,减去 now[k]-=S;             //合并 }}for(j=0;j<B;j++)               //求最优解 {if(i&(1<<j))               //j表示一个没有被拿走的袋子 {for(k=1;k<=G;k++)temp[k]=now[k];int count=0;          //保存收益 for(k=1;k<=G;k++){temp[k]+=map[j][k];while(temp[k]>=S){count++;     //再拿一次 temp[k]-=S;}}if(count>0)         //赚到 dp[i]=max(dp[i],count+dp[i^(1<<j)]);elsedp[i]=max(dp[i],0-dp[i^(1<<j)]);}}}cout<<dp[maxx]<<endl;}return 0;}

原创粉丝点击