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 ...
随机推荐
- Docker Harbor 高可用 1.7.5版本(七)
环境说明: node1 10.10.5.135 仓库 1 node2 10.10.5.136 仓库 2 node3 10.10.5.137 客户端 实验内容: Harbor 可以在两台主机之间相互同步 ...
- Openstack OCATA 安装环境说明(一) 未完成版本
1 Openstack简介: 2 实验说明: 3 图例: 4 实验环境说明: 4.1 ) 网卡说明: 网卡名 网 段 连接方式 说明 eth0 10.10.5.0/24 仅主机网络 内部网络自动以IP ...
- Docker学习笔记之基本命令使用
测试的环境为Ubuntu1804. 1. search命令搜索镜像 sudo docker search centos 搜索centos相关的镜像,可以看到第一个最多星的的centos是官方的镜像,而 ...
- ClickHouse安装使用(单机、集群、高可用)
Clickhouse版本:20.3.6.40-2 安装包地址:https://repo.yandex.ru/clickhouse/rpm/stable/x86_64/ 一.单机版 1.安装依赖 yum ...
- binlog-do-db
如果只是对一个数据库设置,其实没有效果的,其他数据还是会记录binlog的 binlog-ignore-db =database b binlog日志里面将不会记录database b的所有相关的操 ...
- 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!
最近栈长注意到阿里开源了自家的 Mock 工具:TestableMock,该工具号称最轻量.简单.舒适的 Mock 测试工具,功能十分强大,媲美 PowerMock,用法比 Mockito 还要简洁, ...
- ubuntu更新下载软件卡住0% [Connecting to archive.ubuntu.com (2001:67c:1360:8001::23)]
一台ubuntu系统,查看硬件和配置环境的时候发现下载卡住了 根据提示就是有ipv6地址,系统也是配置了ipv6地址的.海外机器,而且可以ping通域名 最佳解决方案 我想出了如何让apt-get再次 ...
- 使用cacti监控linux主机
介绍:使用cacti监控linux主机,需要在linux主机上面安装snmp服务,并修改snmpd.conf文件,指定cacti服务器的地址,然后在cacti的前台界面添加此主机即可,此处以监控cen ...
- Centos 安装postgreSQL9.4.3
rpm -ivh http://download.postgresql.org/pub/repos/yum/9.4/redhat/rhel-7.2-x86_64/pgdg-centos94-9.4-3 ...
- 干货 | 质量保障新手段,携程回归测试平台实践 原创 Sedro 携程技术 2021-01-21
干货 | 质量保障新手段,携程回归测试平台实践 原创 Sedro 携程技术 2021-01-21