UVaLive 5760 Alice and Bob (博弈 + 记忆化搜索)
题意:有 n 堆石子,有两种操作,一种是从一堆中拿走一个,另一种是把两堆合并起来,Alice 先拿,谁不能拿了谁输,问谁胜。
析:某些堆石子数量为 1 是特殊,石子数量大于 1 个的都合并起来,再拿,这是最优的,因为都想另一个输,并且第二种操作是可以翻转胜负的,所以都会先采取第二个操作,但是砘数量为 1 却不是,所以要分开考虑,dp[i][j] 表示,数量为 1 的堆的个数,总的操作数为 j,先手胜还是负。
考虑边界,如果剩下的都是 1 的,那么 i % 3 != 0 先手胜,
如果没有 1了,那么那是 j % 2 != 0 先手胜,
如果 j 只剩下一个了,那么就可以合并到 1,
操作有三种,第一种,从石子为 1 个的堆中拿一个
第二种,从石子不为 1 的堆中拿一个
第三种,把两个堆石子为 1 的进行合并,并放到总操作数中。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#include <numeric>
#define debug() puts("++++")
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define be begin()
#define ed end()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
//#define all 1,n,1
#define FOR(i,n,x) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.in", "r", stdin)
#define freopenw freopen("out.out", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e5 + 10;
const int maxm = 1e6 + 10;
const LL mod = 1000000007;
const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
}
inline int readInt(){ int x; scanf("%d", &x); return x; } int dp[55][1000 * 50+100]; bool dfs(int n, int m){
int &ans = dp[n][m];
if(ans >= 0) return ans;
if(n == 0) return ans = m&1;
if(m == 0) return ans = (n % 3 != 0);
if(m == 1) return ans = dfs(n+1, 0);
if(!dfs(n-1, m)) return ans = 1;
if(!dfs(n, m-1)) return ans = 1;
if(!dfs(n-1, m+1)) return ans = 1;
if(n > 1 & !dfs(n-2, m + 3)) return ans = 1;
return ans = 0;
} int main(){
ms(dp, -1);
int T; cin >> T;
for(int kase = 1; kase <= T; ++kase){
scanf("%d", &n);
int cnt1 = 0, sum = 0;
for(int i = 1; i <= n; ++i){
int x = readInt();
if(x == 1) ++cnt1;
else sum += x;
}
sum += max(0, n - cnt1 - 1);
printf("Case #%d: %s\n", kase, dfs(cnt1, sum) ? "Alice" : "Bob");
}
return 0;
}
UVaLive 5760 Alice and Bob (博弈 + 记忆化搜索)的更多相关文章
- BZOJ 3895 3895: 取石子 / Luogu SP9934 ALICE - Alice and Bob (博弈 记忆化搜索)
转自PoPoQQQ大佬博客 题目大意:给定n堆石子,两人轮流操作,每个人可以合并两堆石子或拿走一个石子,不能操作者输,问是否先手必胜 直接想很难搞,我们不妨来考虑一个特殊情况 假设每堆石子的数量都&g ...
- HDU 4111 Alice and Bob (博弈+记忆化搜索)
题意:给定 n 堆石头,然后有两种操作,一种是把从任意一堆拿走一个,另一种是把一个石子放到另一堆上. 析:整体看,这个题真是不好做,dp[a][b] 表示有 a 堆1个石子,b个操作,操作是指把其他的 ...
- CodeForces 918D MADMAX(博弈+记忆化搜索)
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- uvalive 5760 Alice and Bob (组合游戏,dp)
题目链接: http://vjudge.net/problem/viewProblem.action?id=25636 对于>1的堆,必然会被其中一人全部合并. 然后就是二维dp,dp[非1堆的 ...
- UVALive 5760 Alice and Bob
题意是黑板上有n个数\(S_i\).每次操作可以把其中一个数减1或者将两个数合并为一个数.一个数变为0时,则不能再对其操作. 思路是发现最大的可操作次数为\( \sum S_i\)+(n - 1).\ ...
- hdu 4111 Alice and Bob 记忆化搜索 博弈论
Alice and Bob Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 4597 Play Game (DP,记忆化搜索,博弈)
题意:Alice和Bob玩一个游戏,有两个长度为N的正整数数字序列,每次他们两个,只能从其中一个序列,选择两端中的一个拿走.他们都希望可以拿到尽量大的数字之和, 并且他们都足够聪明,每次都选择最优策略 ...
- 【BZOJ-3895】取石子 记忆化搜索 + 博弈
3895: 取石子 Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 263 Solved: 127[Submit][Status][Discuss] D ...
- HDU 4597 Play Game (记忆化搜索博弈DP)
题意 给出2*n个数,分两列放置,每列n个,现在alice和bob两个人依次从任意一列的对头或队尾哪一个数,alice先拿,且两个人都想拿最多,问alice最后能拿到数字总和的最大值是多少. 思路 4 ...
随机推荐
- 【HQL】小技巧
case1.a与b匹配表保留一条匹配关系 背景:匹配b,b匹配a在同一张表: match_table表为: uid,m_uid 111,222 222,111 需求:只保留一条匹配关系. 结果为: u ...
- 【练习】@property练习题
请利用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution: 写了一段代码 class Screen(object): #利用property ...
- python-反射案例讲解
login.py#!/usr/bin/dev python# coding:utf-8 def index(): print u'欢迎访问xx网站首页' def login(): print u'登录 ...
- Redis内存模型总结
一.Redis内存统计 在客户端通过redis-cli连接服务器后,通过info命令可以查看内存使用情况: info memory 返回结果中比较重要的几个说明如下: (1)used_memory:R ...
- sourcetree合并分支
参考: https://blog.csdn.net/qq_34975710/article/details/74469068
- MySql 的基本使用之连接数据库、选择数据库、查看表结构
1.连接 mysql mysql -u username -p -h host -P port 端口号:默认 3306. 如果是连接本地数据库,可以直接使用 mysql -uroot -p 2.选 ...
- java枚举类型
jvm并不支持枚举类型,java中枚举类型是在编译器层面上实现的,先看如下代码: package demo.nio; public class EnumDemo { public static enu ...
- Linux网络编程学习计划
由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章 概论 P1-16 第二章 UNIX ...
- python 关于文件的操作
1.打开文件: f=open(r'E:\PythonProjects\test7\a.txt',mode='rt',encoding='utf-8') 以上三个单引号内分别表示:要打开的文件的路径,m ...
- php 二维数组按照某个键排序
$date = array_column($arr, 'run_date'); //上面得到的结果:array(0=>'2017-11-21',1=>'2017-11-20',3=> ...