1. 程式人生 > >BZOJ4550 小奇的博弈 【Nimk遊戲 + dp + 組合數】

BZOJ4550 小奇的博弈 【Nimk遊戲 + dp + 組合數】

題目

這個遊戲是在一個1*n的棋盤上進行的,棋盤上有k個棋子,一半是黑色,一半是白色。最左邊是白色棋子,最右邊
是黑色棋子,相鄰的棋子顏色不同。
這裡寫圖片描述
小奇可以移動白色棋子,提比可以移動黑色的棋子,它們每次操作可以移動1到d個棋子。每當移動某一個棋子時,
這個棋子不能跨越兩邊的棋子,當然也不可以出界。當誰不可以操作時,誰就失敗了。小奇和提比輪流操作,現在
小奇先移動,有多少種初始棋子的佈局會使它有必勝策略?

輸入格式

共一行,三個數,n,k,d。對於100%的資料,有1<=d<=k<=n<=10000, k為偶數,k<=100。

輸出格式

輸出小奇勝利的方案總數。答案對1000000007取模。

輸入樣例

10 4 2

輸出樣例

182

題解

面對各種數學轟炸。。跪了。
前置知識:
Nimk遊戲
Nim遊戲基礎上,每次可以取之多d堆

先手必敗條件:每堆石子轉成二進位制,各個位的和都為(d + 1)的倍數
例如可以取2次,石子數:111、101、110、011【二進位制】
每一位都有2+1=3個1,所以先手必敗

本題
黑白棋子相間分佈,白棋右移,黑棋左移,每對棋子的間隔長就相當於石子數,而每次可以操作d次,就相當於Nimk遊戲

求方案數
一共有K/2堆石子,總數不超過N - K個
首先,總的方案數為C(N,K),我們嘗試求出必敗的方案數,作差
f

[i][j]表示每堆石子的二進位制表示中最高位為i位【從0開始算】,總共有j和石子的方案數
那麼有
f[i+1][j+x(d+1)2i]+=f[i][j]C(K/2,x(D+1))

原理:最高第i+1位的方案由最高第i位轉移而來,每次同時加上(D+1)個1,可列舉x,表示加上x(D+1)來進行轉移,而每次加入x(D+1)組石子,又有C(K/2,x(D+1))種方法

【模型的轉化,dp的應用,組合數的使用】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int #define REP(i,n) for (int i = 1; i <= (n); i++) #define Redge(u) for (int k = h[u]; k != -1; k = ed[k].nxt) using namespace std; const int maxn = 10005,maxm = 105,INF = 1000000000,P = 1000000007; LL C[maxn][maxm],f[20][maxn]; int main(){ LL N,K,D; cin>>N>>K>>D; for (int i = 0; i <= N; i++){ C[i][0] = 1; for (int j = 1; j <= i && j <= K; j++) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % P; } f[0][0] = 1; for (LL i = 0; i <= 16; i++) for (LL j = 0; j <= N - K; j++) for (LL x = 0; x * (D + 1) <= K / 2 && x * (D + 1) * (1ll << i) + j <= N - K; x++) f[i + 1][j + x * (D + 1) * (1ll << i)] = (f[i + 1][j + x * (D + 1) * (1ll << i)] + f[i][j] * C[K/2][x * (D + 1)]) % P; LL ans = C[N][K]; for (int i = 0; i <= N - K; i++) ans = (ans - f[16][i] * C[N - K - i + K / 2][K / 2] % P) % P; cout<<(ans + P) % P<<endl; return 0; }

相關推薦

BZOJ4550 博弈 Nimk遊戲 + dp + 合數

題目 這個遊戲是在一個1*n的棋盤上進行的,棋盤上有k個棋子,一半是黑色,一半是白色。最左邊是白色棋子,最右邊 是黑色棋子,相鄰的棋子顏色不同。 小奇可以移動白色棋子,提比可以移動黑色的棋子,它們每次操作可以移動1到d個棋子。每當移動某一個棋子時,

BZOJ1227 SDOI2009 虔誠的墓主人樹狀陣列+合數好題*

BZOJ1227 SDOI2009 虔誠的墓主人 Description 小W 是一片新造公墓的管理人。公墓可以看成一塊N×M 的矩形,矩形的每個格點,要麼種著一棵常青樹,要麼是一塊還沒有歸屬的墓地。當地的居民都是非常虔誠的基督徒,他們願意提前為自己找一塊合

[bzoj4550] 博弈

題目大意 略… 分析 首先單獨分析一對石子(相鄰的且左邊白右邊黑):第一步如果白棋向右走,可以把間隔減小任意步,輪到黑棋的時候,黑棋顯然也可以減小間隔。如果某一方無法縮小間隔,而往另一方向,另一方可以再貼上去,走反方向顯然不是最優的。 然後就可以把一對石

的倉庫(樹形DP)

「題目背景」 小奇採的礦實在太多了,它準備在喵星系建個礦石倉庫。令它無語的是,喵星系的貨運飛船引擎還停留在上元時代! 「問題描述」 喵星系有n個星球,星球以及星球間的航線形成一棵樹。 從星球a到星球b要花費[dis(a,b) Xor M]秒。(dis(a,b)表示ab間的航線長度,Xor為位運算中的異

51Nod1778 Q的集合 合數Lucas定理

In namespace () color MLOG work 影響 AC UC 題目分析: 題解好高深...... 我給一個辣雞做法算了,題解真的看不懂。 註意到方差恒為$0$,那麽其實就是要我們求$\sum_{i=0}^{n}\binom{n}{i}(i^k-(n-i)

HDU-2844 Coins 動態規劃DP+多重揹包

題目傳送門 題目:有n種硬幣,第i種硬幣的價值為Ai,數目為Ci,求這些硬幣能配出1~m中的幾種價值。 題解:dp[j]表示是否能配出價值j。sum[i][j]表示第i種硬幣取到價值j時需要的數目。sum陣列可以壓掉i的那一維,每次都要記得清零。 AC程式碼: #include

POJ-3666 Making the Grade 動態規劃DP+滾動陣列

題目傳送門 題目:輸入n個數,第i個數字的值為a[i],把第i個數變為j的代價為a[i]-j的絕對值,求把這n個數組成的數列變成單調數列的最小代價。 題解:dp[i][j]表示前i個數最大值為b[j]時的最小代價,即第i個數在總數列中的值為第j小的時候的最小代價。 動態轉移方程:dp

POJ-2392 Space Elevator 動態規劃DP+多重揹包

題目傳送門 題目:牛要去太空了!他們計劃通過建造一種太空升降機來達到軌道:一個巨大的積木塔。他們有K (1 <= K <= 400)不同型別的積木來建造塔。型別i的每個塊的高度都是h_i (1 <= h_i <= 100),並且數量上都是c_i (1 <= c_

AtCoder2000Leftmost Ball (DP+合數

題意 Snuke喜歡五顏六色的球。他總共有N×K個球,有N種顏色,每種顏色的球有K個。顏色編號為1到N。他將按照任意順序排列所有球。然後,對於每種顏色,他將該顏色的最左邊的球塗成顏色0,顏色0不同於N

bzoj 3687 簡單題bitset的dp揹包優化bitset的妙用

【題意】 求n個數的所有子集的和的異或值 【分析】     要求計運算元集算術和的異或和。首先我們設dp[i]表示由這n個數能有多少種方案組成i,顯然這樣dp[1~sum]就將所有的子集和統計完了,那麼計算的時候只要判斷(dp[i]&1)就有ans^=i。這樣的

BZOJP2073POI2004PRZ題解狀壓DP+列舉子集

狀壓DP+列舉子集 Code: #include<bits/stdc++.h> using namespace std; int n,W; int w[18],t[18]; int dp

狀壓DP水題[SCOI2005]互不侵犯

題目描述 在N×N的棋盤裡面放K個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各一個格子,共8個格子。 注:資料有加強(2018/4/25) 輸入輸出格式 輸入格式: 只有一行,包含兩個數N,K ( 1

UNITY3D 遊戲開發之七C# 中的委託、事件、匿名函式、Lambda 表示式

"委託是一個類,它定義了方法的型別,使得可以將方法當作另一個方法的引數來進行傳遞,這種將方法動態地賦給引數的做法,可以避免在程式中大量使用If-Else(Switch)語句,同時使得程式具有更好的可擴充套件性。" from: http://www.himigame.com/

Android遊戲開發十七讓玩家自定義手勢玩轉Android遊戲!—Android Gesture之輸入法手勢技術

原創,轉載務必在明顯處註明:轉載自 原文連結: http://www.himigame.com/android-game/340.html很多童鞋說我的程式碼執行後,點選home或者back後會程式異常,如果你也這樣遇到過,那麼你肯定沒有仔細讀完Himi的博文,第十九篇Him

Android遊戲開發十四深入Animation,在SurfaceView中照樣使用Android—Tween Animation!

原創,轉載務必在明顯處註明:轉載自 原文連結: http://www.himigame.com/android-game/331.html很多童鞋說我的程式碼執行後,點選home或者back後會程式異常,如果你也這樣遇到過,那麼你肯定沒有仔細讀完Himi的博文,第十九篇Him

BZOJ1076 [SCOI2008]獎勵關 狀壓dp + 數學期望

1076: [SCOI2008]獎勵關 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3074  Solved: 1599 [Submit][St

Unity3D遊戲開發學習筆記(四)一切都動起來—Animator元件的應用

一、Animation簡介 動畫原本是指由許多連續的圖片在人眼前面快速播放,肉眼因視覺殘像產生錯覺,而誤以為畫面活動的作品。 但在 Unity3D 中的“ Animation”【動畫】 系統應該這樣理解——用於為遊戲者自動播放人物動作或自動演示物體運動路徑、色

Unity3D遊戲開發學習筆記(六)上帝之手—GameObject的操作

在Unity中,所有實體都屬於遊戲物件(GameObject),比如外部匯入到場景中的模型,Unity自帶的立方體等等,而要將這些GameOject進行管理,互動等操作,則需要用到指令碼來實現,上一節我們已經學習瞭如何建立一個指令碼並繫結到一個物體上,現在我們將

UNITY3D 遊戲開發之五Google-protobuf與FlatBuffers資料的序列化和反序列化

★protobuf有啥缺陷?前幾天剛剛在“光環效應 ”的帖子裡強調了“要同時評估優點和缺點”。所以俺最後再來批判一下這玩意兒的缺點。◇應用 不夠廣由於protobuf剛公佈沒多久,相比XML而言,protobuf還屬於初出茅廬。因此,在知名度、應用廣度等方面都遠不如XML。由於這個原因,假如你設計的系統需要提

Android遊戲開發二十物理遊戲之重力系統開發,讓你的遊戲變得有質有量!

原創,轉載務必在明顯處註明:    今天群裡一哥哥說急需關於物理遊戲方面的資料,so~下午就隨手寫了一個簡單的圓形自由落體Demo,正好一起分享給大家學習下吧;    先大概說一下,之前的文章中,給大家介紹過重力感測器,那麼和今天要說的重力系統,其實是一樣的!    在重力感