hdu4778 Gems Fight!
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others)
Total Submission(s): 1912 Accepted Submission(s): 824
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.
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.
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
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.
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
int dp[4200000][2];
int vis[4200000];
int num[30][30];
int p[10]; //把p[]设为全局变量,这样dfs中的一个层改变,总体也改变了
int tot,g,b,s;
void dfs(int state,int turn)
{
int i,j,st,turn1;
int pp[10];
if( state==(1<<b)-1 ){
dp[state][0]=dp[state][1]=0;
return;
}
if(vis[state])return;
dp[state][1]=0;
dp[state][0]=-inf;
int cha=-inf;
for(j=1;j<=8;j++){ //这里要先把p[]备份,因为还要回溯
pp[j]=p[j];
}
for(i=1;i<=b;i++){
int t1=0;
int t2=0;
if(state&(1<<(i-1)) )continue; //这里要选择一个当前状态没有选择过的背包
st=state|(1<<(i-1) );
int cnt=0;
for(j=1;j<=g;j++){
p[j]+=num[i][j];
cnt+=p[j]/s;
p[j]%=s;
}
if(cnt==0){
turn1=1^turn; //这里表示是不是要换成对手拿
}
else turn1=turn;
dfs(st,turn1);
for(j=1;j<=8;j++){
p[j]=pp[j];
}
t1+=cnt;
if(cnt==0){ //如果交换了,那么先手t1的值要加上st状态后手拿的最大值
t1+=dp[st][1];
t2+=dp[st][0];
}
else{
t1+=dp[st][0];
t2+=dp[st][1];
}
if(t1-t2>cha){
cha=t1-t2;
dp[state][0]=t1;
dp[state][1]=t2;
}
}
vis[state]=1; //访问过的状态就不用访问了,相当于剪枝
return ;
}
int main()
{
int n,m,i,j,c,t;
while(scanf("%d%d%d",&g,&b,&s)!=EOF)
{
if(g==0 && b==0 && s==0)break;
memset(num,0,sizeof(num));
for(i=1;i<=b;i++){
scanf("%d",&t);
for(j=1;j<=t;j++){
scanf("%d",&c);
num[i][c]++;
}
}
memset(p,0,sizeof(p));
memset(vis,0,sizeof(vis));
dfs(0,0);
printf("%d\n",dp[0][0]-dp[0][1]);
}
return 0;
}
也可以用状压dp,用dp[state]表示在state状态下先手与后手的最大差距。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 15
int a[25][22],dp[1<<23];
int color[25],color1[25];
int main()
{
int n,m,i,j,T,G,B,S,c,state;
while(scanf("%d%d%d",&G,&B,&S)!=EOF)
{
if(G==0 && B==0 && S==0)break;
memset(a,0,sizeof(a));
for(i=1;i<=B;i++){
scanf("%d",&n);
for(j=1;j<=n;j++){
scanf("%d",&c);
a[i][c]++;
}
}
dp[0]=0;
for(state=1;state<(1<<B);state++){
dp[state]=-inf;
for(i=1;i<=G;i++)color[i]=0;
for(i=1;i<=B;i++){
if((state&(1<<(i-1) ))==0 ){
for(j=1;j<=G;j++){
color[j]+=a[i][j];
color[j]=color[j]%S;
}
}
}
for(i=1;i<=B;i++){
if(state&(1<<(i-1) )){
int state1=(state^(1<<(i-1) ) );
for(j=1;j<=G;j++)color1[j]=color[j];
int cnt=0;
for(j=1;j<=G;j++){
color1[j]+=a[i][j];
cnt+=color1[j]/S;
}
if(cnt!=0) dp[state]=max(dp[state],dp[state1]+cnt);
else dp[state]=max(dp[state],-dp[state1]); //这里没有产生魔法石,所以先后手互换
}
}
}
printf("%d\n",dp[(1<<B)-1]);
}
return 0;
}
hdu4778 Gems Fight!的更多相关文章
- hdu 4778 Gems Fight! 博弈+状态dp+搜索
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...
- hdu 4778 Gems Fight! 状态压缩DP
Gems Fight! Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others)T ...
- HDU 4778 Gems Fight! (2013杭州赛区1009题,状态压缩,博弈)
Gems Fight! Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others)T ...
- Hdu 4778 Gems Fight! (状态压缩 + DP)
题目链接: Hdu 4778 Gems Fight! 题目描述: 就是有G种颜色,B个背包,每个背包有n个宝石,颜色分别为c1,c2............两个人轮流取背包放到公共容器里面,容器里面有 ...
- HDU 4778 Gems Fight!(DP)
题目链接 当我放弃的时候过了.sb啊,卡常数!!! 换了好几个姿势,本来没写预处理,预处理+俩剪枝,尼玛就过了.. #include <stdio.h> #include <stri ...
- hdu 4778 Gems Fight! 状压dp
转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...
- hdu 4778 Gems Fight!
第一次写状压dp-- 题意:http://blog.csdn.net/dyx404514/article/details/15506601 状压dp+博弈吧-- #include<iostrea ...
- Unable to download data from http://ruby.taobao.org/ & don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
安装cocoapods,记录两个问题! 1.镜像已经替换成了 http://ruby.taobao.org/, 还是不能不能安装cocoapods, 报错:Unable to download dat ...
- Australian troops to the fight against Islamic State militants.
He arrived in Arnhem Land on Sunday, honouring an election promise to spend a week every year in an ...
随机推荐
- kubernets之节点和网络的安全保障策略
一 在pod中使用宿主节点的命名空间 1.1 在pod中使用宿主的网络命名空间 [root@node01 Chapter13]# cat pod-with-host-network.yml api ...
- kubernets之pod的标签
一 如何查看pod 的日志 1 通过执行命令查看日志信息 kubectl logs pod_name 二 创建带有标签的pod,一个范例的pod创建yaml文件如下所示 2.1 创建带有 ...
- Pulsar vs Kafka,CTO 如何抉择?
本文作者为 jesse-anderson.内容由 StreamNative 翻译并整理. 以三个实际使用场景为例,从 CTO 的视角出发,在技术等方面对比 Kafka 和 Pulsar. 阅读本文需要 ...
- v-model语法糖
其实v-model就是一个结合了v-bind和v-on的语法糖,实现了双向数据绑定. 举个(栗子):
- 阿里云VOD(二)
一.准备工作 1.设置不转码 测试之前设置默认"不转码",以节省开发成本 2.找到子账户的AccessKey ID 3.给子账户添加授权 AliyunVODFullAccess 4 ...
- Socket.IO基础教程
什么是Socket.IO Socket.IO是一个库,可用于在浏览器和服务器之间进行实时,双向和基于事件的通信.它包括: 使Node.js服务器:来源 | API 为浏览器(可从Node.js的也运行 ...
- java虚拟机入门(一)-jvm基础
转行学java之前,总是听着大佬们说着java像个渣男一样可以跨平台,一次编译到处运行,瞬间,我就坚定了学java的信念,哎呀妈呀,得劲.真的学java之后,好像渣男也不是那么好学的,尤其这货的必杀技 ...
- 一文搞定全场景K3s离线安装
作者简介 王海龙,Rancher中国社区技术经理,负责Rancher中国技术社区的维护和运营.拥有6年的云计算领域经验,经历了OpenStack到Kubernetes的技术变革,无论底层操作系统Lin ...
- 解决Linux下mysql区分大小写的问题
1.查看lower_case_table_names的值,0代表区分大小写,1代表不区分大小写. 通过命令:SHOW VARIABLES LIKE 'lower%'; 1. 解决方法 以root用户登 ...
- EMA algorithm: https://blog.csdn.net/m0_38106113/article/details/81542863
EMA algorithm: https://blog.csdn.net/m0_38106113/article/details/81542863