hdu 4778 Gems Fight! 博弈+状态dp+搜索
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html
题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜索
不难发现,无论Alice和Bob以何种方式投掷包裹,他们得到的Magic Stones个数的和$Sum$是一定的,因此只需要计算Alice可以获得的最大的Magic Stones的个数MAXA,则Bob获得的个数为Sum-MAXA,而两者的最大的差为MAXA-(sum-MAXA)为答案。那么如何计算MAXA呢?我们定义状态state为目前包裹的使用情况,如果包裹i被使用则state的二进制的第i位为0,否则为1。我们可以发现如下性质:
Alice和Bob的目的是相同的,即使得获得的Magic Stones的个数最大。唯一的区别就是Alice先手,而Bob后手。如果Alice这一轮没有获得Magic Stone,那么权利转移给Bob,Bob的策略则和Alice在相同的状态state下先手的策略是相同的。从而可以定义dp[state],表示在先手的情况下(无论是Alice还是Bob)能够获得的最大的Magic Stones数目。从而可以使用深度优先的记忆化搜索。对于一个状态$state$,如果第i个包裹还没有被使用,则计算先手把这个包裹投入cooker中所能获得的magic stone的个数gen,如果gen>0则说明可以继续保持先手,获得的Magic Stones得个数等于此次获得和个数加上在下一个状态下先手投掷所能获得的最大的个数。否则的话先手转化为后手,所获得的Magic Stones的个数只能为此状态下所能产生所有的的Magic stones的个数减去先手在下一状态下所能获得的最大的个数。我们用gen表示此次向cooker中投掷i包裹能够获得的magic的个数,cc表示cooker的状态,即各个颜色石头的个数。left表示目前状态下所能产生的所有的Magic stones的个数。
代码如下:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
const int MAXB = ;
const int MAXC = ;
const int MIN = -;
int g, b, s;
int bag[MAXB][MAXC];
int color[MAXC];
int dp[<<MAXB];
int dfs(int state,int left, int *c)
{
if( state == || left == ) return ;
if( dp[state] != MIN ) return dp[state];
int maxres = MIN;
int maxtmp = ;
for( int i = ; i < b ; i++ )
{
int cc[MAXC];
memset(cc, , sizeof(cc));
int gen = ;
if( state>>i & )
{
for( int j = ; j < g ; j++ )
{
cc[j] = c[j] + bag[i][j];
gen += cc[j]/s;
cc[j] %= s;
}
if( gen > )
{
maxtmp = gen + dfs(state^(<<i), left-gen, cc);
}
else
{
maxtmp = left - dfs(state^(<<i), left, cc);
}
}
maxres = max(maxres, maxtmp);
}
dp[state] = maxres;
return maxres;
}
int main(int argc, char *argv[])
{
while( )
{
scanf("%d%d%d", &g, &b, &s);
if( g == && b == && s == ) return ;
memset(bag, , sizeof(bag));
memset(color, , sizeof(color));
int sum = ;
for( int i = ; i < b ; i++ )
{
int tmpn;
scanf("%d", &tmpn);
while( tmpn -- )
{
int c;
scanf("%d", &c);
bag[i][c-]++;
color[c-]++;
}
}
for( int i = ; i < g ; i++ )
{
sum+=color[i]/s;
}
for( int i = ; i < (<<MAXB) ; i++ )
{
dp[i] = MIN;
}
int cc[MAXC];
memset(cc, , sizeof(cc));
int res = dfs((<<MAXB)-, sum, cc);
printf("%d\n", res-(sum-res));
}
}
hdu 4778 Gems Fight! 博弈+状态dp+搜索的更多相关文章
- 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)
题目链接: Hdu 4778 Gems Fight! 题目描述: 就是有G种颜色,B个背包,每个背包有n个宝石,颜色分别为c1,c2............两个人轮流取背包放到公共容器里面,容器里面有 ...
- 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
Gems Fight! Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others)T ...
- HDU 4778 Gems Fight!(DP)
题目链接 当我放弃的时候过了.sb啊,卡常数!!! 换了好几个姿势,本来没写预处理,预处理+俩剪枝,尼玛就过了.. #include <stdio.h> #include <stri ...
- hdu 4778 Gems Fight!
第一次写状压dp-- 题意:http://blog.csdn.net/dyx404514/article/details/15506601 状压dp+博弈吧-- #include<iostrea ...
- hdu 5135(2014广州—状态dp)
t题意:给你n条边,构造任意个三角形,一个三角形恰好只用3条边,每条边只能一次,求面积最大值 思路: 最开始想的是先排序从大到小取,但感觉并不怎么靠谱. 最多12条边,所以可以求出所有可能的三角形面积 ...
- hdu 5025 Saving Tang Monk 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...
- HDU 4778 状压DP
一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...
随机推荐
- JavaScript学习笔记之下拉选择框的操作
对于下拉框的操作十分繁多,这几天项目须要就总结一下 一.动态构建option 有时候我们须要动态构建下拉选择框里面的值,这里我们就要用到 var varItem = new Option(" ...
- ValueStack基础:OGNL
ValueStack基础:OGNL 要了解ValueStack,必须先理解OGNL(Object Graphic Navigatino Language)! OGNL是Struts2中使用的一种表达式 ...
- C#_dropdownlist_3
DropDownList则与TextBox等控件不同,它使用的是select标记.它需要两个值:在下拉框中显示的列表,和默认选项.而自动绑定一次只能绑定一个属性,因此你需要根据需要选择是绑定列表,还是 ...
- 【转】字符串分割(C++)
原文:http://www.cnblogs.com/MikeZhang/archive/2012/03/24/mysplitfuncpp.html 经常碰到字符串分割的问题,这里总结下,也方便我以后使 ...
- 【大坑】DataGridView多线程更新修改Cell单元格卡死
最新发现是Column的AutoSizeMode设置为AllCell调整宽度而造成的卡顿,还有就是在现在里面使用Invoke用匿名函数闭包的形式访问For循环的i变量值会不正确导致找不到索引而造成卡顿 ...
- 各I/O模型 对应Web服务应用模型(select,poll,epoll,kevent,"/dev/poll")
一.利用select多路复用I/O的Web服务应用模型 /* 可读.可写.异常三种文件描述符集的申明和初始化.*/ fd_set readfds, writefds, exceptionfds; F ...
- 关于Eclipse插件开发(五)-----编辑器类方法的使用说明
上面有讲ChinaEditor类继承EditorPart抽象类时,只实现了init,createPartControl两个方法,本节将逐步讲解其他的5个方法的用法. EditorPart方法的执行情况 ...
- 关于Eclipse平台的使用和开发第一个SWT程序
IBM把投入巨资开发的Eclipse作为一个开源项目捐献给了开源组织Eclipse.org Eclipse出色而有独创的平台特性,现在仍由IBM子公司OTI(主要从事Eclipse开发的人)继续领导着 ...
- 本地环境phpStorm10+XDebug配置和断点调试
安装环境:XAMPP;phpStorm版本10; windows 7 64bit. XAMPP.phpStorm 都直接安装在了D盘根目录,9999m目录建在D:\xampp\htocts下,即目录工 ...
- [记录]Ubuntu下,使用Shell,简单替换有规律的文件名称
因工作中需要将Flash转为Html5,并且要有动画效果,我将Flash的组件导出Png序列,然后将Png序列拼接成一张雪碧图(Sprite),名字为在生成雪碧图可以排序,需要改成数字名称. 而名字是 ...