HDU 4371 AliceBob之生成数列直到大于n或者小于等于S(i-2)-思维-(由已知条件推最优步骤)

题意:已知n、d1、d2....dm,Alice先生成一个数S1=0,Bob再生成一个数S2=S1+dk,之后他们生成的数遵循这样的条件:Si=S(i-1)+dk,或者Si=S(i-1)-dk,其中1<=k<=m,S(i-2)<Si<=n。最先写不出一个符合上述条件的数的人输。

分析:

既然想不出什么直接搜索之类的方法,那么一定就是找规律了。这题我们来推一下他的条件得到每个人每一步的最利于自己的做法。

考虑三个数:S(i-2),S(i-1),Si,假设当前步骤是生成Si,那么必须满足的条件是S(i-2)<Si<n,又因为Si是由S(i-1)得到的,用上面的公式带入条件不等式有两种情况,我们分开讨论:

1.Si=S(i-1)+dk

那么对于S(i-1)这个人(设为A)来说,他想让Si(设为B)输,所以A在生成S(i-1)的时候肯定是想构造一个数S(i-1),让B无论怎么选择dk都不能由S(i-1)生成合法的Si。

不合法的Si也就是Si<=S(i-2)并且Si>n,也就是说即使选择最小的dmin也不能满足S(i-1)-dmin>S(i-2)或者S(i-1)+dmin<=n,又因为S(i-1)=S(i-2)+dk,带入得:

S(i-2)+dk-dmin<=S(i-2) 且 S(i-2)+dk+dmin>n,满足这两个条件的dk只能是dmin,所以A在生成S(i-1)的时候为了使B输,他会选择+dmin

2.Si=S(i-1)-dk

推理方法同理,你会发现这个不能在生成自己的时候陷害别人,所以这个不是最利于自己的做法。

综上,每个人每一步都会选择最利于自己的做法是+dmin,之后就模拟一遍,然后谁先>n就谁输。

博弈问题一般解法:根据条件推出每人最利于自己的做法然后:1.模拟一遍得出结果;2.根据数据特征如奇偶性直接判断出结果

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define INF 1000000007
using namespace std;
int t,n,m;
int d;
int main()
{
     scanf("%d",&t);
	 for(int cas=1;cas<=t;cas++){
	 	scanf("%d%d",&n,&m);
	 	int mi=INF;
	 	for(int i=0;i<m;i++){
	 		scanf("%d",&d);
	 		mi=min(mi,d);
	 	}
	    int a=0,b=mi;
	    int ok;
	    if(mi>n) ok=1;
	    else{
		    	while(1){
			    	int tmp=a;
			    	a=b+mi;
			    	b=a+mi;
			    	if(a>n){
			    		ok=0;break;
			    	}
			    	if(b>n){
			    		ok=1;break;
		    	    }
		        }
	    }
	    printf("Case #%d: ",cas);
	    if(ok) printf("Alice\n");
	    else printf("Bob\n");
	 }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 21:02:01

HDU 4371 AliceBob之生成数列直到大于n或者小于等于S(i-2)-思维-(由已知条件推最优步骤)的相关文章

已知一个函数rand5()能够生成1-5的随机数,请给出一个函数,该函数能够生成1-7的随机数。

这是朋友去笔试的一道题,有点考智商,当时我还很自信的说 random5+random5/2  不就可以了 他说不行,然后我就在网上搜了一下 有一道类似的题目 题目: 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数,该函数能够生成1-10的随机数. 思路: 假如已知一个函数能够生成1-49的随机数,那么如何以此生成1-10的随机数呢? 解法: 该解法基于一种叫做拒绝采样的方法.主要思想是只要产生一个目标范围内的随机数,则直接返回.如果产生的随机数不在目标范围内,则丢弃该值,重新取

已知可生成0~4的rand5(),实现生成0~6的rand7()

若已知生成0~6的rand7(),求生成0~4的rand5(),则一个方法就是不断生成0~7的数,直到这个数满足0~4就返回. int rand5(){ int res; do{ res = rand7(); }while(res >4); return res; } 现在已知生成0~4的rand5(),求解生成0~6的rand7(),就是想办法利用rand5()去生成0~大于6的数字,可以使用rand5()+rand5()*5,这个式子可以生成0~24的随机数,每个数字的组成只有一种可能,所以

已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。

描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数. 输入 第一行为M,表示测试数据组数.接下来M行,每行包含一个测试数据. 输出 输出M行,每行为对应行的n-1位数(忽略前缀0).如果除了最高位外,其余位都为0,则输出0. 样例输入 4 1023 5923 923 1000 样例输出 23 923 23 0我的程序: #include<iostream>#include<vector>#include<cmat

Java循环练习:已知s=1×2×3×…×n,计算出s不大于5000时n的最大值

package practiceGO; /*    1.已知s=1×2×3×-×n,计算出s不大于5000时n的最大值.  */ public class Cto { public static void main(String[] args) { int s = 1; for(int n=2; ;n++){ s = s*n; if (s>5000) { System.out.println(n-1);//s大于5000时,n回退一步即s不大于5000时的值 break; } } } } 运行结

HDU 1465 2045 已知结果往前推

1465 不容易系列之一 Time Limit: 1000 MS Memory Limit: 32768 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了!做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理一样.话 虽这样说,

HDU - 6096 :String (AC自动机,已知前后缀,匹配单词,弱数据)

Bob has a dictionary with N words in it. Now there is a list of words in which the middle part of the word has continuous letters disappeared. The middle part does not include the first and last character. We only know the prefix and suffix of each w

HDU 4371 Alice and Bob

Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 691    Accepted Submission(s): 420 Problem Description Alice and Bob are interested in playing games. One day, they invent a game w

HDU 5297 Y sequence Y数列

题意:给定正整数n和r.定义Y数列为从正整数序列中删除全部能表示成a^b(2 ≤ b ≤ r)的数后的数列,求Y数列的第n个数是多少. 比如n = 10. r = 3,则Y数列为2 3 5 6 7 10 11 12 13 14,第10个数是14. 非常有趣的一道数论题.题目给出的范围是long long范围的. 所以显然不用去枚举每一个数了,更不用说推断每一个数是不是某个数的某次方.那么这个题怎么下手呢.首先我们能够非常直观的想到,被删去的数显然是非常分散的.由于能表示成某个数的幂这种形式的数非

HDU 1005 Number Sequence(数列)

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) [Description] [题目描述] A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Given A, B, and n, you are to calculate the