2011 ACM-ICPC 成都赛区A题 Alice and Bob (博弈动规)
题目大意:
有K堆石子,每堆有Ki个。两人的操作能够是:
1 从某一堆拿走一个 假设该堆在此之后没有石子了。就消失
2 合并两个堆
求是否先手必胜,先手胜输出Alice。否则输出Bob
思路:
这道题读完后毫无头绪。推了半天也推不个所以然来,參看大神代码后,感觉就是一个记忆化搜索啊,唉,知识学多了不会用还是白搭。还得多做题啊!
这里我们把数字分成 1,2,大于等于3的奇数,大于等于4的偶数四类。
这样分的原因在于。一个大于3的奇数是实际上等价于3的;由于每当对手减一个。自己也减一个。就又变回了一个大于3的奇数。终于变成3。
同理。全部大于2的偶数等价于4。
所以我们用dp[a][b][c][d]表示有a个1,b个2,c个3,d个4是不是一个必胜态,然后动规求解就好了。
代码:
#include <stdio.h>
#define N 51 bool dp[N][N][N][N] = {0};
bool vis[N][N][N][N] = {0}; int F(int a, int b, int c, int d) // 一个相似记忆化搜索的过程
{
if(!vis[a][b][c][d]){ // 假设后继状态为P状态,则此状态为N状态
if(a >= 1 && !F(a - 1, b, c, d)) dp[a][b][c][d] = 1; // 从 a 中某堆拿走一个。消失
if(b >= 1 && !F(a + 1, b - 1, c, d)) dp[a][b][c][d] = 1; // 从 b 中某堆拿走一个。变成 a
if(c >= 1 && !F(a, b + 1, c - 1, d)) dp[a][b][c][d] = 1; // 从 c 中某堆拿走一个。变成 b
if(d >= 1 && !F(a, b, c + 1, d - 1)) dp[a][b][c][d] = 1; // 从 d 中某堆拿走一个,变成 c if(a >= 2 && !F(a - 2, b + 1, c, d)) dp[a][b][c][d] = 1; // 合并 a 中的两堆,变成 b 类的一堆
if(b >= 2 && !F(a, b - 2, c, d + 1)) dp[a][b][c][d] = 1; // 合并 b 中的两堆,变成 d 类的一堆
if(c >= 2 && !F(a, b, c - 2, d + 1)) dp[a][b][c][d] = 1; // 合并 c 中的两堆,变成 d 类的一堆
if(d >= 2 && !F(a, b, c, d - 2 + 1)) dp[a][b][c][d] = 1; // 合并 d 中的两堆,变成 d 类的一堆 if(a >= 1 && b >= 1 && !F(a - 1, b - 1, c + 1, d)) dp[a][b][c][d] = 1; // 合并 a、b 中的一堆,变成 c 类的一堆
if(a >= 1 && c >= 1 && !F(a - 1, b, c - 1, d + 1)) dp[a][b][c][d] = 1; // 合并 a、c 中的一堆。变成 d 类的一堆
if(a >= 1 && d >= 1 && !F(a - 1, b, c + 1, d - 1)) dp[a][b][c][d] = 1; // 合并 a、d 中的一堆,变成 c 类的一堆
if(b >= 1 && c >= 1 && !F(a, b - 1, c - 1 + 1, d)) dp[a][b][c][d] = 1; // 合并 b、c 中的一堆,变成 c 类的一堆
if(b >= 1 && d >= 1 && !F(a, b - 2, c, d - 1 + 1)) dp[a][b][c][d] = 1; // 合并 b、d 中的一堆。变成 d 类的一堆
if(c >= 1 && d >= 1 && !F(a, b, c - 1 + 1, d - 1)) dp[a][b][c][d] = 1; // 合并 c、d 中的一堆,变成 c 类的一堆 vis[a][b][c][d] = 1;
} return dp[a][b][c][d];
} int main()
{
int loop, n, t, ct = 1;
int a, b, c, d, ans; // a 表示仅仅有一个石子的堆数,b 表示有仅仅有两个石子的堆数。c 表示有奇数个石子的堆数, d 表示有偶数个石子的堆数
scanf("%d", &loop);
while(ct <= loop){
scanf("%d", &n);
a = b = c = d = 0;
for(int i = 0; i < n; i ++){
scanf("%d", &t);
if(t == 1) a ++;
else if(t == 2) b ++;
else if(t % 2 == 1) c ++;
else d ++;
} ans = F(a, b, c, d);
printf("Case #%d: ", ct ++);
if(ans)
printf("Alice\n");
else
printf("Bob\n");
} return 0;
}
2011 ACM-ICPC 成都赛区A题 Alice and Bob (博弈动规)的更多相关文章
- 2011 ACM/ICPC 成都赛区(为2013/10/20成都现场赛Fighting)
hdu 4111 Alice and Bob 博弈:http://www.cnblogs.com/XDJjy/p/3350014.html hdu 4112 Break the Chocolate ...
- 2013年山东省第四届ACM大学生程序设计竞赛E题:Alice and Bob
题目描述 Alice and Bob like playing games very much.Today, they introduce a new game. There is a polynom ...
- hdu 4461 第37届ACM/ICPC杭州赛区I题
题意:给两个人一些棋子,每个棋子有其对应的power,若b没有或者c没有,或者二者都没有,那么他的total power就会减1,total power最少是1,求最后谁能赢 如果b或c出现的话,fl ...
- hdu 4460 第37届ACM/ICPC杭州赛区H题 STL+bfs
题意:一些小伙伴之间有朋友关系,比如a和b是朋友,b和c是朋友,a和c不是朋友,则a和c之间存在朋友链,且大小为2,给出一些关系,求出这些关系中最大的链是多少? 求最短路的最大距离 #include& ...
- zoj 3662 第37届ACM/ICPC长春赛区H题(DP)
题目:给出K个数,使得这K个数的和为N,LCM为M,问有多少种 f[i][j][k]表示选i个数,总和为j,最小公倍数为k memery卡的比较紧,注意不要开太大,按照题目数据开 这种类型的dp也是第 ...
- 2017 ACM/ICPC 新疆赛区 I 题 A Possible Tree 带权并查集
传送门 题意:给定一棵带权树的形态, 但是并不知道每天条边的具体权重. 然后给m个信息, 信息格式为u v val, 表示在树上u 到 v 的路径上经过的边的权重的异或和为val, 问前面最多有多少个 ...
- hdu 4462 第37届ACM/ICPC 杭州赛区 J题
题意:有一块n*n的田,田上有一些点可以放置稻草人,再给出一些稻草人,每个稻草人有其覆盖的距离ri,距离为曼哈顿距离,求要覆盖到所有的格子最少需要放置几个稻草人 由于稻草人数量很少,所以状态压缩枚举, ...
- hdu 4463 第37届ACM/ICPC杭州赛区K题 最小生成树
题意:给坐标系上的一些点,其中有两个点已经连了一条边,求最小生成树的值 将已连接的两点权值置为0,这样一定能加入最小生成树里 最后的结果加上这两点的距离即为所求 #include<cstdio& ...
- hdu 4438 第37届ACM/ICPC 天津赛区现场赛H题
题意:Alice和Bob两个人去打猎,有两种(只)猎物老虎和狼: 杀死老虎得分x,狼得分y: 如果两个人都选择同样的猎物,则Alice得分的概率是p,则Bob得分的概率是(1-p): 但是Alice事 ...
随机推荐
- 第3节 mapreduce高级:8、9、自定义分区实现分组求取top1
自定义GroupingComparator求取topN GroupingComparator是mapreduce当中reduce端的一个功能组件,主要的作用是决定哪些数据作为一组,调用一次reduce ...
- 允许IIS下载无后缀文件及“请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理。”的解决方法
1)增加MIME类型 ,如下 application/octet-stream 2)注意是"." , ".*"则适用于任何有文件后缀时使用,无后缀请不要加*
- Linux从入门到适应(三):Ubuntu16.04将python从3.5升级到3.6
1 将python从默认的python2.7更换为python3.5 : sudo update-alternatives --install /usr/bin/python python /usr/ ...
- 全国绿色计算大赛 模拟赛第一阶段(Python)
第1关求和 class Task: def getSum(self, num1, num2): sum = 0 for i in range(num1, num2 + 1): while (i != ...
- vuex相关(actions和mutation的异曲同工)
vuex说明: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 包含的内容: state: ...
- KBE实践——登录案例
目录 服务器 ``` void maini(){ printf("hello world"); } ``` 最小资产库创建 entity配置 实体的Python实现 创建第一个空间 ...
- Python使用Flask框架,结合Highchart,自定义导出菜单项目及顺序
参考链接: https://www.highcharts.com.cn/docs/export-module-overview https://api.hcharts.cn/highcharts#ex ...
- buf.slice()
buf.slice([start[, end]]) start {Number} 默认:0 end {Number} 默认:buffer.length 返回:{Buffer} 返回一个指向相同原始内存 ...
- ubuntu lamnp 环境的安装/卸载 及 配置
安装mysql--------------------------------------sudo apt install mysql-server #5.7版本 安装php----------- ...
- C语言学习2
C语言能够进行嵌套备注的方法: #if(0) do { scanf("%d", &n); getchar(); }]||n>a[M-]); #endif