uva11758 解題報告(神博弈之一)

2021-07-08 10:10:55 字數 2035 閱讀 3293

題目鏈結

題意:給你乙個一維的棋盤,大小為n,然後給你k個棋子,k一定為偶數,有k/2個灰棋子,k/2個白棋子,灰色和白色一定成對擺放(先灰後白)然後兩個人,a,b,每次可以進行一種操作,可以選擇其中d個棋子(a只能選灰,b只能選白)讓這個棋子左移或者右移任意步(至少要選擇乙個棋子移動一步)問你一共有多少種擺放方式,使得先手必勝

解析:

分析之,灰色棋子向左是無意義的,(後手進行相同的推進操作,局面不變)同理,白色棋子向右也無意義。所以我們只考慮灰色向右和白色向左。那麼這樣看來,每對棋子就是乙個nim遊戲。

不過因為先手可以選擇d堆進行操作,求先手必勝的狀態必然複雜度很高,那麼反之,用總的擺法減去後手必勝就是先手必勝。

對於這樣k堆的nim,每次選擇1-d堆進行操作,有乙個定理,就是a1,a2,a3...ak的每位二進位制的和一定要是(d+1)的倍數(可以為0)這樣就是後手必勝的條件。

至於為什麼這樣,簡單說說,不嚴格證明。

假設a1,a2,a3...ak的二進位制位寫開(每個數占一列,從最低位到第18位(一般18即可,不夠再加)) 對於每行都滿足1的個數為d+1的倍數,我們稱這個狀態為平衡態。先手遇到此平衡態必敗。如果先手隨意破壞此平衡態,對於後手來說,因為也可以選至多d個數,然後再把先手每拿掉的一些位上的1拿掉即可(這樣比較抽象,可以這麼理解,就是10個糖果,最多拿d個最少拿乙個,當然必勝策略就是你的對手拿了a個,你就拿d+1-a個不就行了(平衡態後手必勝策略))

明白了這個結論之後,假設a1,a2,...,ak都已經確定,那麼沒確定的就是他的擺放位置,和a1,a2...ak多大沒有半毛錢關係。然後這道題就成了一道dp計數的問題(類似數字dp)dp[i][j]表示前行,權和為j的個數)乙個數字的揹包就這樣了。列舉這一行1的個數m滿足d+1|m,進行一次選擇就行了,最後再計算這樣的a1-ak有多少種擺法(把每堆打包插入,排列組合)

演算法就是醬紫

//

// created by matrix on 2015-11-26

////

//#pragma comment(linker, "/stack:102400000,102400000")

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define all(x) x.begin(), x.end()

#define ins(x) inserter(x, x,begin())

#define ll long long

#define clr(x) memset(x, 0, sizeof x)

using

namespace

std;

const

int inf = 0x3f3f3f3f;

const ll mod = 1e9 + 7;

const

int maxn = 1e2 + 10;

const

int maxv = 1e3 + 10;

const

double eps = 1e-9;

int t;

int n, k, d;

ll c[maxn * 100][maxn];

ll dp[20][maxv * 10];

int main()

}while(t--) }}

ll ans = c[n][2*k];

// printf("ans = %lld\n", ans);

for(int i = 0; i <= n - 2 * k; i++)

cout

<< ans << endl;

}return

0;}

UVa 755 487 3279解題報告

第一道超時題目,資料量太大達到100000,如果要乙個乙個手動模擬比較,肯定會超時。看了別人的 都是用到了stl的map容器。果然是神器,如果不用map還真不知道怎麼在3秒內輸出結果。用了map是1秒多。很清晰,就沒寫注釋。include include include include includ...

uva839解題報告

題目大意就是根據幹槓平衡原理,判斷題目所給出的資料組成的天平能否平衡。注意,此天平可能包含子天平。輸入時,如果w為0,則表示包含子天平,子天平按照先左後右的方法輸入。解題思路 這是二叉樹的問題,資料的輸入就好比先序遍歷。判斷有無子節點就是判斷w是否為0 本題需要思考兩點 第乙個如何判斷子天平平和 第...

UVA540解題報告

挺簡單的一道模擬題,用來做stl或資料結構的練習題還是不錯的。注意的是這次用到了不止乙個佇列而是1000個,還有就是同乙個隊的要編號。附上ac time 30ms include include includeusing namespace std const int maxn 1000 10 ch...