這個遊戲是在乙個1*n的棋盤上進行的,棋盤上有k個棋子,一半是黑色,一半是白色。最左邊是白色棋子,最右邊是黑色棋子,相鄰的棋子顏色不同。
小奇可以移動白色棋子,提比可以移動黑色的棋子,它們每次操作可以移動1到d個棋子。每當移動某乙個棋子時,這個棋子不能跨越兩邊的棋子,當然也不可以出界。當誰不可以操作時,誰就失敗了。小奇和提比輪流操作,現在小奇先移動,有多少種初始棋子的布局會使它有必勝策略?
共一行,三個數,n,k,d。對於100%的資料,有1<=d<=k<=n<=10000, k為偶數,k<=100。
輸出小奇勝利的方案總數。答案對1000000007取模。
首先思考k=2的情況,顯然白棋可以直接往右移到黑棋左邊,然後黑棋只能被動往右移,然後白棋又可以不斷向右將黑棋逼死,所以如果一開始中間的間隔不為0則先手必勝,反之先手必輸。
k>2的情況同理,白棋是一定不會主動往左移的,黑棋也一定不會主動往右移,所以黑白之間的間隔一定會不斷變小,這變成了什麼?我們將間隔視為石子,那麼這就相當於k堆石子,沒人可以從1-d堆中取出若干個石子。這是乙個經典的nimk問題。
關於nimk的解法可以看:nimk遊戲的演算法與證明
#include
using
namespace std;
typedef
long
long ll;
const ll mod=
1e9+7;
ll f[20]
[10010
],ans;
ll c[
10010][
110]
;int n,k,d;
intmain()
for(
int i=
0;i<
16;i++
)for
(int j=
0;j<=n-k;j++
)for
(int l=0;
(1ll
<
*(d+1)
*l<=j&&
(d+1
)*l<=k/
2;l++
) f[i+1]
[j]=
(f[i+1]
[j]+f[i]
[j-(
1ll<
*l*(d+1)
]*c[k/2]
[(d+1)
*l])
%mod;
for(
int i=
0;i<=n-k;i++
) ans=
(ans+f[16]
[i]*c[n-i-k/2]
[k/2])
%mod;
printf
("%lld"
,(c[n]
[k]-ans+mod)
%mod)
;}
BZOJ 4550 小奇的博弈 knim 揹包
hzwer,感覺博弈裡面的各種結論好多好自閉啊orztime limit 2 sec memory limit 256 mb submit 207 solved 126 submit status discuss 這個遊戲是在乙個1 n的棋盤上進行的,棋盤上有k個棋子,一半是黑色,一半是白色。最左邊...
BZOJ 4548 小奇的糖果
有 n 個彩色糖果在平面上。小奇想在平面上取一條水平的線段,並拾起它上方或下方的所有糖果。求出最多能夠拾 起多少糖果,使得獲得的糖果並不包含所有的顏色。包含多組測試資料,第一行輸入乙個正整數 t 表示測試資料組數。接下來 t 組測試資料,對於每組測試資料,第一行輸入兩個正整數 n k,分別表示點數和...
BZOJ4547 小奇的集合
有乙個大小為n的可重集s,小奇每次操作可以加入乙個數a b a,b均屬於s 求k次操作後它可獲得的s的和的最大值。資料保證這個值為非負數 很顯然,我們每次肯定是取集合中最大的兩個數,那麼我們設這兩個數為 a b,當前的和為 s 顯然有轉移 a b,b a b,s a b s,那麼用矩陣乘法加速即可。...