【解题报告】博弈专场 (CF 2000~2200)前五题
生活随笔
收集整理的這篇文章主要介紹了
【解题报告】博弈专场 (CF 2000~2200)前五题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【解題報告】博弈專場 (CF 2000+)前五題
- A:Fox and Card Game | CF388C
- 題意
- 思路
- 代碼
- B:Berzerk | CF786A
- 題意
- 思路
- 代碼
- C:Ithea Plays With Chtholly | CF896B
- 題意
- 思路
- 代碼
- D:Lieges of Legendre | CF603C
- 題意
- 思路
- 代碼
- E:Funny Game | CF731E
- 題意
- 思路
- 代碼
- 博弈專場 (CF 2000+)十題
這里面假設每個人都是聰明的,不會犯錯,希望自己的收益最大。
A:Fox and Card Game | CF388C
題意
- Fox and Card Game | CF388C
有 nnn 堆牌,第 iii 堆有 aia_iai? 張牌,每堆牌從上往下,給出每張牌的分數
兩個人輪流拿牌,AliceAliceAlice 選一堆牌,拿走這堆牌的最上面那張牌;BobBobBob 則是選一堆,拿走這堆牌的最下面那張牌。 - 選完后,計算每個人的分數和,大的獲勝。求每個人的最終分數。
∑ai≤104\sum a_i\le 10^4∑ai?≤104
思路
- 一開始感覺是無從下手的,選擇決策有很多。
如果靠近牌頂有收益很大的,肯定是 AliceAliceAlice 能拿到的。但是她可以不一開始就去拿。當 BobBobBob 拿了這堆的底的時候,她再來拿這堆的頂即可,有點像圍棋的下法和思路。 - 這么一看,每堆牌就是一個獨立的游戲。那么我們只考慮一堆牌。如果是偶數牌,AliceAliceAlice 拿走前一半, BobBobBob 拿走后一半。如果是奇數,那么中間那張牌會被先手拿走。
- 如果考慮多堆奇數牌,先手拿走中間的某張牌后,先手就會變成后手,后手會拿走另一堆中間的某張牌。所以我們把奇數牌堆的中間那張牌的收益降序,然后雙方輪流拿即可。
代碼
- 時間復雜度:O(nlog?n)O(n\log n)O(nlogn)
B:Berzerk | CF786A
題意
- Berzerk
有 nnn 個球,編號 1~n1\sim n1~n,環形排成一圈,第 nnn 個球是黑洞。
AliceAliceAlice 有一個前進集合 AAA,BobBobBob 有一個前進集合 BBB
對于每一個開始位置 ppp,雙方輪流選擇他集合中的一個數,相當于他順時針走幾步。如果走到黑洞,他就贏了。 - 求對于每一個 ppp,對于每個人先手的情況,是必勝還是必輸,或者是平局。
2≤n≤70002\le n\le 70002≤n≤7000
思路
- 會跑循環,貌似挺麻煩的。考慮到多起點單終點,我們倒著跑是一個不錯的選擇。
我們可以定義 dp[i][0/1]dp[i][0/1]dp[i][0/1] 表示在這個位置,誰先手,的必勝態怎么樣。
如果下一步,都走到對方的必勝態,自己就是必敗態。如果下一步,有一步走到對方的必敗態,自己就是必勝態。
否則,就是平局。 - 感覺寫起來挺麻煩的。倒著走,都走到必勝態,我們可以用一個 cntcntcnt 數組去做。
平局,我們可以使用一個 visvisvis 數組去做。
代碼
- 時間復雜度:O(n2)O(n^2)O(n2)
C:Ithea Plays With Chtholly | CF896B
題意
- Ithea Plays With Chtholly | CF896B
有 nnn 張紙,一開始沒有都是空。
有 mmm 輪,每一次給定一個 [1,c][1,c][1,c] 的數字。
給你數字之后,你需要選擇把它寫在那一張紙上,若紙上之前寫過數字,則覆蓋。
你需要擺完一個數字,他才給你下一個數字。
問你怎么擺,讓最后 nnn 張紙上的數字非單調遞減。 - n,m≥2n,m\ge 2n,m≥2
1≤c≤10001\le c\le 10001≤c≤1000
1≤n??c2?≤m≤10001\le n \cdot \lceil \frac{c}{2}\rceil \le m\le 10001≤n??2c??≤m≤1000
思路
- 非常神奇的交互題。也是一開始感覺擺數字讓最后非單調遞減,策略比較復雜的感覺。
但是仔細想想,假設它最開始給了你個 111,你擺在最左邊是毫無疑問的。
假設最開始給了你個 222,你擺在最左邊好像也可以,但如果再給了你個 111,你擺成 [2,1][2,1][2,1] 就很劣,不如把 222 替換成 111 - 經過上述非常離散的思考,我們感覺一直維護一個非單調遞減的序列就可以了,做法有點類似求最長上升子序列的過程。
- 但是這樣 WAWAWA了。再次仔細考慮,我們的次數超過了 mmm 輪了。假設它給你 [1,c][1,c][1,c] 范圍內的數字,給你 ccc 的話,你放在最右位置是毫無疑問的。
于是,憑感覺,我們把值分成小值和大值,序列從左往右維護一個小值的非遞減序列,從右往左維護一個大值的非遞增序列。這樣,次數就夠了。 - 嚴格分析輪數的話,考慮最劣情況的維護非遞增序列的次數,即給定序列為 [x,x?1,x?2,?,1,x,x?1,?][x,x-1,x-2,\cdots,1,x,x-1,\cdots][x,x?1,x?2,?,1,x,x?1,?],即可以分析得到輪數的最劣情況就是 n??c2?n \cdot \lceil \frac{c}{2}\rceiln??2c??
代碼
- 時間復雜度:O(nlog?n)O(n\log n)O(nlogn)
D:Lieges of Legendre | CF603C
題意
- Lieges of Legendre | CF603C
nnn 堆石頭,每堆有 aia_iai? 個石頭。
兩個人輪流拿石頭。每次可以:
(1) 選擇一堆,拿走其中一個石頭
(2)選擇一堆,這堆的石頭個數為 2x2x2x,把它用 kkk 堆石頭,每堆 xxx 個石頭替換
誰不能拿就輸了。求先手是否必勝。 - 1≤n≤1051\le n\le 10^51≤n≤105
1≤ai,k≤1091\le a_i,k\le 10^91≤ai?,k≤109
思路
- 石頭,考慮 SGSGSG 值。
設 f(x)f(x)f(x) 表示 xxx 個石頭的 SGSGSG 值。
一個可以轉移到 f(x?1)f(x-1)f(x?1)
若 xxx 是偶數,可以變成 kkk 個 f(x/2)f(x/2)f(x/2) 的異或值。 - 容易想到按照 kkk 的奇偶性分類討論。
- 如果 kkk 是偶數,我們能算出來 f[0,1,2]={0,1,2}f[0,1,2]=\{0,1,2\}f[0,1,2]={0,1,2}
如果 xxx 是奇數,那么可以得到 f(x)=mex{f(x?1)}f(x)=mex\{f(x-1)\}f(x)=mex{f(x?1)}
如果 xxx 是偶數,那么可以得到 f(x)=mex{f(x?1),0}f(x)=mex\{f(x-1),0\}f(x)=mex{f(x?1),0},因為 kkk 個 f(x/2)f(x/2)f(x/2) 的異或值為 000
我們可以直接得到 f(x)=0f(x)=0f(x)=0,如果 xxx 是大于 222 的奇數;f(x)=1f(x)=1f(x)=1,如果 xxx 是大于 222 的偶數。 - 如果 kkk 是奇數,我們能算出來 f[0,1,2,3,4]={0,1,0,1,2}f[0,1,2,3,4]=\{0,1,0,1,2\}f[0,1,2,3,4]={0,1,0,1,2}
如果 xxx 是奇數,仍然 f(x)=mex{f(x?1)}f(x)=mex\{f(x-1)\}f(x)=mex{f(x?1)}
如果 xxx 是偶數,那就 f(x)=mex{f(x?1),f(x/2)}f(x)=mex\{f(x-1),f(x/2)\}f(x)=mex{f(x?1),f(x/2)} 因為 kkk 個 f(x/2)f(x/2)f(x/2) 的異或值為 f(x/2)f(x/2)f(x/2)
我們能得到一個結論,如果 xxx 是大于 444 的奇數,那么 f(x)=0f(x)=0f(x)=0。否則,f(x)>0f(x)>0f(x)>0,我們可以歸納法去做,假設成立,然后根據 mex{f(x?1)}mex\{f(x-1)\}mex{f(x?1)} 可以證明。
我們接下來只要遞歸計算 f(x)f(x)f(x) ,xxx 是偶數的情況即可。每次都除以 222,是在 log?\loglog 的數量級可以求出來的。 - 當然有人說:結論怎么想得出來的?你可以打表找規律,但是記得按 kkk 的奇偶性去看。
代碼
- 時間復雜度:O(nlog?n)O(n\log n)O(nlogn)
E:Funny Game | CF731E
題意
- Funny Game | CF731E
有 nnn 個數,兩個人輪流操作。
每一次,選擇至少兩個,把最左邊的 xxx 個數字合并成一個新的數字,值為這 xxx 個數字的和 yyy,操作的人獲得 yyy 分。
選完后,第一個人的分數減去第二個人的分數的差值為 CCC,第一個人希望讓 CCC 最大,第二個人希望讓 CCC 最小,你需要求出這個 CCC。 - 2≤n≤2×1052\le n\le 2\times 10^52≤n≤2×105
思路
- 每次就是選擇一個前綴和,設 dp[i][0/1]dp[i][0/1]dp[i][0/1] 表示已經選擇好前 iii 個數了,接下來由哪個人開始選。
寫下狀態轉移方程:
dp[i][0]=max?{dp[j][1]+pre[j]}dp[i][0]=\max\{dp[j][1] + pre[j]\}dp[i][0]=max{dp[j][1]+pre[j]}
dp[i][1]=min?{dp[j][0]+pre[j]}dp[i][1]=\min\{dp[j][0] + pre[j]\}dp[i][1]=min{dp[j][0]+pre[j]}
然后考慮暴力做時間不夠的,只要記錄一個最大值和最小值,直接轉移即可。 - 注意至少選擇兩個,也就是說我們的答案是 dp[1][0]dp[1][0]dp[1][0] 而不是 dp[0][0]dp[0][0]dp[0][0]
- 還有別的更簡單的做法。考慮每個操作的人都是希望最大化自己的分數的,所以可以寫成:
也是非常的妙。
代碼
- 時間復雜度:O(n)O(n)O(n)
總結
以上是生活随笔為你收集整理的【解题报告】博弈专场 (CF 2000~2200)前五题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序:数独挑战之九宫格-中级-第一
- 下一篇: 【论文阅读笔记】Explaining A