Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 1649 | Accepted: 931 |
Description
In this game, you have a winning strategy. To see this, you first remove four stones and leave 96 stones. No matter how I play, I will end up with leaving 92 - 95 stones. Then you will in turn leave 91 stones for me (verify this is always possible). This way, you can always leave 5k+1 stones for me and finally I get the last stone, sigh. If we initially had 101 stones, on the other hand, I have a winning strategy and you are doomed to lose.
Let's generalize the game a little bit. First, let's make it a team game. Each team has n players and the 2n players are seated around the table, with each player having opponents at both sides. Turn around the table so the two teams play alternately. Second, let's vary the maximum number of stones each player can take. That is, each player has his/her own maximum number of stones he/she can take at each turn (The minimum is always one). So the game is asymmetric and may even be unfair.
In general, when played between two teams of experts, the outcome of a game is completely determined by the initial number of stones and the maximum number of stones each player can take at each turn. In other words, either team has a winning strategy.
You are the head-coach of a team. In each game, the umpire shows both teams the initial number of stones and the maximum number of stones each player can take at each turn. Your team plays first. Your job is, given those numbers, to instantaneously judge whether your team has a winning strategy.
Incidentally, there is a rumor that Captain Future and her officers of Hakodate-maru love this game, and they are killing their time playing it during their missions. You wonder where the stones are? Well, they do not have stones but do have plenty of balls in the fuel containers!
Input
n S M1 M2 . . . M2n
where n is the number of players in a team, S the initial number of stones, and Mi the maximum number of stones ith player can take. 1st, 3rd, 5th, ... players are your team's players and 2nd, 4th, 6th, ... the opponents. Numbers are separated by a single space character. You may assume 1 <= n <= 10, 1 <= Mi <= 16, and 1 <= S < 2^13.
Output
Sample Input
1 101 4 4 1 100 4 4 3 97 8 7 6 5 4 3 0
Sample Output
0 1 1
dp[i][j]是轮到第i个人取石子时还剩j个,是否是必胜态。
显然如果已经没有石子可取是必胜态。
如果后继状态中存在必败态,那么当前状态是必胜态。
用记忆化搜索写起来很方便。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MAXN = 11000;
int dp[25][MAXN];
int a[25];
int n,s;
int dfs(int cur,int num){
if(dp[cur][num]!=-1)
return dp[cur][num];
if(num==0)
return dp[cur][num]=1;
int next=cur==2*n?1:cur+1;
for(int i=1;i<=min(a[cur],num);i++){
if(dfs(next,num-i)==0)
return dp[cur][num]=1;
}
return dp[cur][num]=0;
}
int main(){
while(scanf("%d",&n)&&n){
scanf("%d",&s);
for(int i=1;i<=2*n;i++)
scanf("%d",a+i);
memset(dp, -1, sizeof(dp));
if(dfs(1,s)==1)
puts("1");
else
puts("0");
}
}
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 1094 | Accepted: 353 |
Description
Alice and Bob are playing a game. At the beginning, the judge takes out a stone pile of W stones and a black box containing N cards. Every card has a number Ai on it. Alice and Bob takes turns to draw a card from the box. Of course, they will not know the number until they draw the card out of the box. The player then takes away Ai stones from the pile if it is possible. If there are not enough stones, the player draws a card again. The winner is the player who takes away the last stone. Once the box gets empty, they brings back all cards and stones and play the game again until there is a winner.
Now your best friend Alice begs you, the judge, to help her cheat in the game. You have already known the number of cards in the box and their numbers. Given a integer M, You want to know how many values, less or equal to M, W can take so that you can make sure Alice will be the winner of the game.
Input
There are several test cases.
The first line of each test case contains two integers N (1 ≤ N ≤ 10000) and M (1 ≤ M ≤ 100000).
The second line contains N integers Ai (1 ≤ Ai ≤ M). The input ends with two zeros
Output
For each test case output how many values you can choose for W so that Alice will be the winner without fail.
Sample Input
3 8 1 5 7 0 0
Sample Output
3
Hint
每个人轮流按抽到的卡片取出石块,Alice已经知道卡片的位置和数组,问有多少个小于等于w的值有必胜策略。
这个题的思路比较巧妙。
对于每一个w的最后结果,要不然就是由奇数张牌构成,要不然就是由偶数张牌构成。
如果这个w只能由奇数张牌构成就是必胜态。
想到这点就很容易写了。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MAXN = 101000;
bool dp[MAXN][2];//dp[i][0]=true代表可以由偶数张牌构成,dp[i][1]=true代表可以由奇数张牌构成
int a[MAXN];
int main(){
int n,m;
while(scanf("%d%d",&n,&m)){
if(n==0&&m==0)
break;
for(int i=0;i<n;i++)
scanf("%d",a+i);
sort(a,a+n);
memset(dp, false, sizeof(dp));
dp[a[0]][1]=true;
for(int i=1;i<n;i++){
for(int j=m;j>a[i];j--){
if(dp[j-a[i]][0])
dp[j][1]=true;
if(dp[j-a[i]][1])
dp[j][0]=true;
}
dp[a[i]][1]=true;
}
int res=0;
for(int i=1;i<=m;i++){
if(dp[i][1]&&!dp[i][0])
res++;
}
printf("%d\n",res);
}
}