题目链接
最近搞了搞博弈论。发现了这个k倍动态减法。。看了不少题解仍然是不知所云。无奈只能先记下来板子。
对于我们构造出的序列a。如果n在这个序列n里面,就得出先手必输。否则,先手可以那最小的构成a[h]数量的石块。
下面是ac代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <cstdlib>
#include <algorithm>
#define ll long long
using namespace std;
const int N = 20000005;
int a[N], b[N];
int init(int n, int k)
{
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];
else
b[i] = a[i];
}
return i;
}
int main()
{
int t;
cin >> t;
int t0 = 1;
while(t--)
{
int n, k;
scanf("%d%d", &n, &k);
printf("Case %d: ", t0++);
int h = init(n, k);
if (a[h] == n) puts("lose");
else
{
int ans;
while(n)
{
if (n >= a[h])
{
n -= a[h];
ans = a[h];
}
h--;
}
printf("%d\n", ans);
}
}
return 0;
}