UVALive 5760 Alice and Bob

题意是黑板上有n个数\(S_i\)。每次操作可以把其中一个数减1或者将两个数合并为一个数。一个数变为0时,则不能再对其操作。

思路是发现最大的可操作次数为\( \sum S_i\)+(n - 1)。\( \sum S_i\)是把所有数消除需要的操作数。(n-1)表示我们最多可以合并(n-1)次。

同时我们发现,总操作数的奇偶决定了胜负。换言之,合并的次数决定论胜负。

当1个数为1时,假如我们将其消去,则合并的次数减1,总操作数的奇偶改变。

那么我们首先考虑,所有的数都>=2的情况,假如这种情况对应的最大的可操作次数为先手胜。那么因为所有数>=2,所以无论后手怎么操作,最多把某个数变为1。当后手把某个数变为1,先手将这个1与其他数合并,则不改变最大的可操作次数。

换言之,当每个数都>=2时,其最后的操作总数必然等于最大的可操作次数。也就是说,假如没有数是1,那么胜负则已经决定了。

所以我们对每个状态,只需要用1的个数和非1的数的个数,即可表示。

那么我们用one表示1的个数,m表示非1的数的总可操作数。

对于所有非1的数字,其变为1的情况只有m=1一种。

所以我们用dp(one,m)即可表示每个状态。然后扫其后续状态即可。具体的状态转移,看代码吧。

代码如下:

 1 #include"cstdio"
 2 #include"iostream"
 3 #include"cstring"
 4 #include"algorithm"
 5 #include"cstdlib"
 6 #include"vector"
 7 #include"set"
 8 #include"map"
 9 #include"cmath"
10 using namespace std;
11 typedef long long LL;
12 const LL MAXN=30;
13
14 int f[60][60000];
15 int sg(int one,int m)
16 {
17     if(f[one][m]!=-1) return f[one][m];
18
19     if(one==0) return f[one][m]=((m%2)==1);
20     if(m==1) return f[one][m]=sg(one+1,0);
21
22     if(!sg(one-1,m)) return f[one][m]=1;        // one中移出1个
23
24     if(m>0 && !sg(one,m-1)) return f[one][m]=1;    // m操作1次
25
26     if(m>0 && !sg(one-1,m+1)) return f[one][m]=1;    // one中移动一个到m
27
28     if(one>=2)                             // 两个one合并
29     {
30         if(m>0 && !sg(one-2,m+3)) return f[one][m]=1;
31         else if(m==0 && !sg(one-2,m+2)) return f[one][m]=1;
32     }
33
34     return f[one][m]=0;
35 }
36 int main()
37 {
38 #ifdef LOCAL
39     freopen("in.txt","r",stdin);
40     // freopen("out.txt","w",stdout);
41 #endif
42     memset(f,-1,sizeof(f));
43     int t;
44     scanf("%d",&t);
45     for(int tt=1;tt<=t;tt++)
46     {
47         int n,one=0,m=0;
48         scanf("%d",&n);
49         for(int i=1;i<=n;i++)
50         {
51             int tmp;
52             scanf("%d",&tmp);
53             if(tmp==1) one++;
54             else m+=(tmp+1);
55         }
56         if(m) m--;
57         printf("Case #%d: ",tt);
58         if(sg(one,m)) printf("Alice\n");
59         else printf("Bob\n");
60     }
61     return 0;
62 }
时间: 2024-10-05 12:51:01

UVALive 5760 Alice and Bob的相关文章

codeforces_346A Alice and Bob(数学)

题目链接:http://codeforces.com/problemset/problem/346/A 参考链接:http://blog.csdn.net/loy_184548/article/details/50174615 感受到数学在博弈论中的强大. 考虑最后终止状态的序列-无法取出任意两个数他们的差值不存在这个序列中:那么这必定是个首项等于公差的等差序列 而这个序列是 d 2d 3d....,因此可以通过a[1] a[2] a[3] ...的最大公约数得到 然后计算有几个数没在数组中,判

HDU4268 Alice and Bob 【贪心】

Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2869    Accepted Submission(s): 926 Problem Description Alice and Bob's game never ends. Today, they introduce a new game. In this

博弈问题-Alice与Bob拿牌游戏

Description Bob and Alice play a game, and Bob will play first. Here is the rule of the game: 1) There are N stones at first; 2) Bob and Alice take turns to remove stones. Each time, they can remove p^k stones. p is prime number, such as 2, 3, 5, ...

Alice and Bob

Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Description It is so boring in the summer holiday, isn't it? So Alice and Bob have invented a new game to play. The rules are as follows. First, they get a se

HDU 4111 Alice and Bob (博弈)

Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1799    Accepted Submission(s): 650 Problem Description Alice and Bob are very smart guys and they like to play all kinds of games i

HDU 4268 Alice and Bob(贪心+multiset)

HDU 4268 题意:Alice与Bob在玩卡片游戏,他们每人有n张卡片,若Alice的一张卡片长与宽都不小于Bob的一张卡片,则Bob的卡片就会被盖住,一张卡片只可以使用一次,且不可旋转求Alice最多可以盖住多少张Bob的卡片. 思路:记录两人卡片情况,并按照长度将两人卡片分别降序排序.遍历两人的卡片,将长度小于Alice的卡片长度的Bob卡片的宽度插入multiset中,在multiset中找到小于等于Alice卡片宽度的第一个数,将这个数给消去且答案+1.//贪心法自行发挥即可. co

HDU 4268 Alice and Bob(贪心+Multiset的应用)

 题意: Alice和Bob有n个长方形,有长度和宽度,一个矩形可以覆盖另一个矩形的条件的是,本身长度大于等于另一个矩形,且宽度大于等于另一个矩形,矩形不可旋转,问你Alice最多能覆盖Bob的几个矩形? 思路:贪心,先按照h将Alice和Bob的矩形排序,对于Alice的每个矩形,如果Bob的矩形的h小于Alice的h,将Bob的w插入到集合中. 然后,在集合中找到不大于Alice矩形d的最大的Bob的d,那么这样做肯定是最优的. #include<cstdio> #include<

ZOJ 3666 Alice and Bob (SG博弈)

题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3666 题意: 给一个有向图,然后A和B轮流移动棋子,棋子在每一个位置可以重叠,当某人不能走时,输! 问A和B谁赢 方法: 显然每一局游戏都是独立的,对每一局游戏异或即可 每一局游戏的结果可以用SG求,记忆化搜索之 1 int dfs(int x) 2 { 3 if (sg[x] != -1) return sg[x]; 4 bool vis[maxn]; 5 me

Sdut 2108 Alice and Bob(数学题)(山东省ACM第四届省赛D题)

题目地址:sdut 2608 Alice and Bob Alice and Bob Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Alice and Bob like playing games very much.Today, they introduce a new game. There is a polynomial like this: (a0*x^(2^0)+1) * (a1 * x^(2^1)+1)*....