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拿走且满足变换 ...
随机推荐
- Spring3 MVC Login Interceptor(Spring 拦截器)
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 08重编终极版《东邪西毒:终极版》DVD粤语中字
1.东邪西毒].Ashes.of.Time.1994.384p.DVDRip.x264.ac3-DTMM.mkv 这个版本最清晰 ,可惜删减了,只有87分钟,粤语,1.4G. 2.东邪西毒(初始版). ...
- Aizu 2309 Sleeping Time DFS
Sleeping Time Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view ...
- git在windows下clone、pull或者push内存溢出的解决办法
发现国内使用git来真正管理源码的人不多,特别是大数据量的源码,今天使用git clone android的源码时突然出现remote out of memery,解决办法: git config - ...
- 图像的稀疏表示——ScSPM和LLC的总结
前言 上一篇提到了SPM.这篇博客打算把ScSPM和LLC一起总结了.ScSPM和LLC其实都是对SPM的改进.这些技术,都是对特征的描述.它们既没有创造出新的特征(都是提取SIFT,HOG, RGB ...
- 详解Android ActionBar之二:ActionBar添加Tabs标签和下拉导航
本节主要讲解ActionBar如何添加Tabs标签和下拉导航. 一.添加标签 Tabs 在ActionBar中实现标签页可以实现android.app.ActionBar.TabListener ,重 ...
- C 队列顺序存储
#ifndef __MY_SEQLIST_H__ #define __MY_SEQLIST_H__ typedef void SeqList; typedef void SeqListNode; // ...
- UNIX标准化及实现之选项
POSIX.1的2001版,包括了ISO C标准所指定的各个函数.其接口分成了两类:必需接口和可选接口.可选接口按功能又进一步分成50个区.表1中按它们各自的选项代码总结了没有被弃用的编程接口.选项代 ...
- 原 Debian设置开机自动启动与关闭
发表于1年前(2013-01-08 13:01) 阅读(2380) | 评论(0) 2人收藏此文章, 我要收藏 赞0 开机自动启动 update-rc.d chkconfig 熟悉debian系统 ...
- Mysql数据库备份和按条件导出表数据
Mysql数据库备份和按条件导出表数据 一.备份数据库 # mysqldump -u root -p dbcurr>/home/20090219.sql mysqldum为备份命令,- ...