dd 和 mm 正在玩取石子遊戲。他們的遊戲規則是這樣的:桌上有若干石子,dd 先取,輪流取,每次必須取質數個。如果某一時刻某一方無法從桌上的石子中取質數個,比如說剩下 0 個或 1 個石子,那麼他/她就輸了。
dd 和 mm 都很聰明,不管哪方存在乙個可以必勝的最優策略,他/她都會按照最優策略保證勝利。於是,dd 想知道,對於給定的桌面上的石子數,他究竟能不能取得勝利呢?
當 dd 確定會取得勝利時,他會說:「不管 mm 選擇怎樣的取石子策略,我都能保證至多 x 步以後就能取得勝利。」那麼,最小的滿足要求的 x 是多少呢?注意,不管是 dd 取一次石子還是 mm 取一次石子都應該被計算為「一步」。
第一行有乙個整數 n,表示這個輸入檔案中包含 n 個測試資料。
第二行開始,每行有乙個測試資料,其中僅包含乙個整數,表示桌面上的石子數。
你需要對於每個輸入檔案中的 n 個測試資料輸出相應的 n 行。
如果對於該種情形是 dd 一定取得勝利,那麼輸出最小的 x。否則該行輸出 -1。
很好的一道dp題,先dp求出是否一定贏。
f[0]=f[1]=0;表示當石子個數為零或一時一定輸。
f[m] 為零的必要條件是 f[m-所有可能質數]=1;
f[m] 為1的必要條件是 存在 f[m-可能質數]=0;
求步數就比較難辦了。
出題者說 若 f[i]==1 ,那麼存在 f[i-可能質數]=0;這時取最大值,因為另一方在知道自己一定會輸的情況下會搗亂:-d
若 f[i]==0,那麼 f[m-所有可能質數]=1;這時取最小值,因為這次另一方一定會贏,所以不搗亂。
1 #include2using
namespace
std;34
int n,m,f[20001],d[20001];5
int a[2262]=;89
int max(int a,int
b)12
13int
main()
1430
31for(int i=2;i<=m;++i)
3236
else
if(!f[i]&&f[i-a[j]])
37}
3839
if(f[m]==0)
4041 cout4243}44
//system("pause");
45return0;
4647 }
質數取石子
dd 和 mm 正在玩取石子遊戲。他們的遊戲規則是這樣的 桌上有若干石子,dd 先取,輪流取,每次必須取質數個。如果某一時刻某一方無法從桌上的石子中取質數個,比如說剩下 0 個或 1 個石子,那麼他 她就輸了。dd 和 mm 都很聰明,不管哪方存在乙個可以必勝的最優策略,他 她都會按照最優策略保證勝...
動態規劃 質數取石子
題目描述 dd 和 mm 正在玩取石子遊戲。他們的遊戲規則是這樣的 桌上有若干石子,dd 先取,輪流取,每次必須取質數個。如果某一時刻某一方無法從桌上的石子中取質數個,比如說剩下 0 個或 1 個石子,那麼他 她就輸了。dd 和 mm 都很聰明,不管哪方存在乙個可以必勝的最優策略,他 她都會按照最優...
Cogs 56 質數取石子 博弈
質數取石子 輸入檔案 stonegame.in 輸出檔案 stonegame.out 簡單對比 時間限制 1 s 記憶體限制 128 mb 問題描述 dd 和 mm 正在玩取石子遊戲。他們的遊戲規則是這樣的 桌上有若干石子,dd 先取,輪流取,每次必須取質數個。如果某一時刻某一方無法從桌上的石子中取...