B ***游戏
链接:https://www.nowcoder.com/acm/contest/190/B
 来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
 空间限制:C/C++ 32768K,其他语言65536K
 64bit IO Format: %lld
题目描述
Alice和Bob产生了不可调节的矛盾,于是他们相约一起玩一个***游戏,输的人就会从这个世界上消失。 游戏开始时,Alice手上拿着一个定时炸弹,炸弹有个倒计时t。炸弹在t=0时刻会爆炸,此时手上拿着炸弹的人会从这个世界上消失。为了增加游戏乐趣,他们约定每个人拿到炸弹后可以选择将炸弹的时间调快d秒(d ∈ [a,b]),或者不调。每次交换炸弹会消耗1秒(假设调节炸弹时间不需要消耗时间)。 问题来了,如果双方都足够聪明,谁会活下去呢?
 输入描述:
 第一行有三个整数t,a,b,分别表示炸弹初始时刻的倒计时,可调节时间的范围。(0 ≤ t ≤ 105,1 ≤ a ≤ b ≤ 10)
 输出描述:
 若Alice存活则输出"Alice",若Bob存活则输出"Bob"。
示例1
输入
 6 3 4
 输出
 Alice
说明
 Alice只需要将炸弹调快3秒后再给Bob,Bob就会拿到一个2秒后爆炸的炸弹。
f[0]为必败状态 f[i-1]==0 必然 f[i]是必胜状态
 当f[i-1]==1 时 看f[i-1-b]到f[i-1-b] 状态有没有必败状态 就可以认定f[i]是必胜状态
 // 博弈真的很神奇 orz
官方题解:
 将必胜态和必败态的转移用 DP 递推或者记忆化搜索出来即可。 一个必败态的后继状态全部是必胜态,一个必胜态的后继存在比败态
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
 
int n,m,t,k,a,b; 
int f[maxn];
 
int main(){
	while(cin>>t>>a>>b){
		memset(f,0,sizeof(f));
		for(int i=1;i<=t;i++){
			if(f[i-1]==0) f[i]=1;
			else{
				for(int j=max(0,i-b-1);j<=max(-1,i-a-1);j++){// 这里wa几发 边界orz
					if(f[j]==0){// i-a-1 小于0 不能成0结束 而是不访问
						f[i]=1;
						break;
					}
				}
			}
		}
		if(f[t]) cout<<"Alice\n";
		else cout<<"Bob\n";
	}
    return 0;
}

 京公网安备 11010502036488号
京公网安备 11010502036488号