您的位置:首页 > 其它

ZOJ-3599 Game (博弈 K倍动态减法)

2014-05-03 17:26 381 查看
GameTime Limit: 3 Seconds      Memory Limit: 65536 KBAlice and Bod decide to play a new stone game. At the beginning Alice puts n(n>1) stones (out of N in all) on the table. Alice and Bob remove the stones inturn. At each step the player should remove some number of stones. The number of stones the player removed should be at least one, and cannot exceed m times of the number of stones the player removed at the last step. The player who removes the laststone wins the game. Alice always plays first and of course at the first turn, she cannot remove all the stones. Alice wants to know how many positive integers nshe can choose to win the game if both players play optimally.Since you're an ace programmer, Alice wants you to help her.

Input

There are multiple test cases. The first line of input contains an integer T (0 < T ≤ 500) indicating the number of test cases. Then T test cases follow.Each test case is a line of 2 integers m and N(0 < m ≤ 2012, 1 < N < 231)

Output

For each test case output the number of positive integers Alice can choose for n to make her win the game.

Sample Input

3
1 10
2 10
3 10

Sample Output

6
5
4
思路:
博弈K倍动态减法的一个变形,k倍动态减法详见 http://blog.csdn.net/tbl_123/article/details/24884861[/code] 
题意大概是先手先从N个中选出n(n < N)个,两人轮流从n中取,遵循k倍动态减法的规则,若要保证先手必赢,问n有几种选法;
这里我们只需找出构造的数列中比N小的数的个数(即0...N中必败态的个数),再另N-i或N-i-1,即为先手可以选出得个数了
代码:
#include <stdio.h>#define N 3000000long long a, b;int main(){long long n;int k, loop = 0, casei = 1;scanf("%d", &loop);while(loop --){scanf("%d%lld", &k, &n);a[0] = b[0] = 1;int i = 0, j = 0;while(n > a[i]){i ++;a[i] = b[i - 1] + 1;while(a[j + 1] * k < a[i])j ++;if(k * a[j] < a[i])b[i] = b[j] + a[i];elseb[i] = a[i];}if(n == a[i])printf("%lld\n", n - i - 1);elseprintf("%lld\n", n - i);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  博弈 k倍动态减法