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

9 篇文章 0 订阅
4 篇文章 0 订阅

 

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 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

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.

 题目大意:有B个盒子里面放有G种颜色的宝石,两个人轮流选一个盒子将其中的宝石取出来放到一个锅里,然后其中没有S个相同颜色的宝石,它们就会聚合在一起变成一个魔法石(可能产生多个魔法石且锅里有可能有剩余的宝石),然后本轮的得分就是产生的魔法石的数量,且如果本轮某个人拿到了魔法石的话,那么下一轮他还可以继续选择盒子放入宝石,知道他在某一轮没有拿到魔法石,现在问两个人都采用最优策略的情况下,到最后先拿的那个人的得分与后拿的人的得分的差是多少。


解题思路:注意到,总共可以取到的魔法石个数是固定的,可以事先预处理出来。b的范围较小,自然想到用二进制表示当前状态,0表示未取,1表示已经取了。而后进行深搜(x表示当前状态)f [ x ] 表示在x局面下先手所能取到的最多魔法石,每次挑一个背包(例如0010可以转移为1010,0110,0011),若选取当前背包后可以得到新的魔法石(数量记为tol),则回合继续,f [ x ] = max(  f [ x ] , t + dp( x | k) ),k=1<<i,i表示新取的背包索引。若没有拿到新的魔法石,则为对方回合,根据递归定义 ,f [ x ] = max(  f [ x ] , t - dp( x | k) ),k=1<<i 注意搜索边界 f [ (1<<b)-1]=0。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define M 0x3f3f3f3f
int b,g,s,n,a;
int color[10],bag[50][10];
int now[20],f[1<<22];
int dp(int x){
	if(f[x]!=-1) return f[x];
	int tmp[20],ans=-11111111;
	memcpy(tmp,now,sizeof tmp);
	for(int i=0;i<b;i++){
		int k=1<<i;
		if(!(x&k)){
			int tol=0;
			for(int j=1;j<=g;j++){
				now[j]+=bag[i][j];
				tol+=now[j]/s;
				now[j]%=s;
			}
			if(tol>0){
				ans=max(ans,tol+dp(x|k));
			}else{
				ans=max(ans,tol-dp(x|k));
			}
		memcpy(now,tmp,sizeof tmp);
		}
		
	}
	return f[x]=ans;
}

void init(){
	memset(color ,0,sizeof color);
	memset(bag,0,sizeof bag);
	memset(f,-1,sizeof f);
	f[(1<<b)-1]=0;
}
int main(){
	while(cin>>g>>b>>s){
		if(!g && !b && !s) break;
		init();
		for(int i=0;i<b;i++){
			cin>>n;
			while(n--){
				cin>>a;
				color[a]++;
				bag[i][a]++;		
			}	
		}
		int msum=0;
		for(int i=1;i<=g;i++){
			msum+=color[i]/s;
		}
		cout<<dp(0)<<endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值