日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

闲来无事刷水题、简单博弈论专题、sg函数、洛谷

發布時間:2023/12/3 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闲来无事刷水题、简单博弈论专题、sg函数、洛谷 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天閑來無事,不想刷codeforces了,到洛谷提高組訓練營找幾道水題刷著玩玩(雖然自己早已過了打OI的年紀)~

簡單博弈論專題

P1199 三國游戲

這么考慮,由于電腦總是不能讓我搭配出當前能搭配出的最大的組合,也就是說我不管選哪個英雄,都不可能匹配出該英雄能搭配出的最大的默契值,那么我最大能搭配出的默契值就是所有英雄匹配中,次大默契值的最大值。
假設有a、b、c、da、b、c、d四位英雄
aa能匹配的最大值為aMaM次大值為amam
bb能匹配的最大值為bMbM次大值為bmbm
cc能匹配的最大值為cMcM次大值為cmcm
dd能匹配的最大值為dMdM次大值為dmdm

假設其中am>bm>cm>dmam>bm>cm>dm

那么我能得到的最大可能值也就是amam了。
下面證明,電腦能組合出的最大值一定比amam要小。
那么我一開始選擇aa,電腦一定會選擇與aa能形成aMaM的值的英雄,假設是dd。
然后我再選cc,這里假設caamc與a組合得到am。
那么電腦會選擇bb。
反證法開始了:
假設dbt>am>dmd與b形成的默契值t>am>dm
daaM>am>dmd與a形成的默契值為aM>am>dm
這樣的話dmdm不可能是dd能匹配到的次大值,矛盾。
所以t<amt<am更大的數。
隨后我們只需要破壞掉電腦構造成最大的組合就可以了。

P1288 取數游戲II

如果出發點靠著0邊,那么只能往一個方向走,并且走過的邊的值一定要減到0,不然對面會逆過來,然后把邊減到0,這樣我方就輸了。

不靠0邊的時候,如果沿著某個方向走會贏,那么就把沿路經過的邊設置為0。
如果沿著那個方向走都不會贏,你任取一個方向走的時候不把邊設置為0,對方在下一次走的時候也會繼續沿著這個方向,并把下一條邊設置成0,你還是要一直沿著這個方向走。

所以不管怎么樣,經過的邊都會變成0,也就是說一旦選定方向了,就只能一直走。
所以結果很固定,你只要把2個方向都老老實實沿著走下去,有一種情況能贏就能贏,否則就不能贏。

P1290 歐幾里德的游戲

典型的輾轉相除法。

假設這時候狀態是(a,b)滿a>b(a,b)滿足a>b
如果[a/b]=1[a/b]=1那么(a,b)(a,b)(b,a%b)(b,a%b)的狀態是相反的。
如果[a/b]=k>1[a/b]=k>1那么就是必勝的,因為如果(b,a%b)(b,a%b)是必敗態,那么a直接剪去k個b,否則的話,a剪去k-1個b。很簡單是不是。

P2148 [SDOI2009]E&D

山東的省選題,中規中矩。
由于多個組是獨立游戲,所以Nim博弈,直接求出所有組的sg函數,然后異或就可以了,如果異或值為0則必敗,否則必勝。
由于每個二元組(a,b)(a,b)的范圍都是1e91e9,這樣的話,sg函數的復雜度太大了,所以要想想辦法。
方法就是:打表找規律!2333
規律如下:

int sg(int x,int y){if(x == 1 && y == 1)return 0;if(x%2 && y%2)return 0;if(x%2) swap(x,y);if(y%2 == 0){return sg(x/2,y/2)+1;}else{return sg(x,y+1);} }

P1247 取火柴游戲

簡單的不像話,跟上面的題難度一樣,方法也一樣,求sg函數,然后異或。
不同的地方是,這個要求第一步的方案。

在必勝態的時候,異或得到的值為ans。
我們第一步要做的就是拿掉一堆中的某些火柴,然后使異或值變為0。
假設我們要拿掉第i堆的某些火柴,那么這一堆應該剩下的火柴的數目就是ansans xor n[i]n[i],拿走的火柴數目就是n[i]?n[i]? (ansans xor n[i]n[i])。
從小到達枚舉堆數,找一個合法的情況就好了。

P2575 高手過招

這到也是sg函數?異或。
不得不說sg函數是博弈論的大殺器呀。
求sg函數的方法就不說了,注意的點:

  • 這題要用到位運算,壓縮狀態,不然時間、空間可能不夠。
  • 開O2!!!

代碼

#include <iostream> #include <cstdio> #include <set> #include <cstring> #include <unordered_map> using namespace std; const int maxn = 2e6; int T,n,m; int sg[maxn]; int grundy(int status){if(sg[status] != -1)return sg[status];unordered_map<int,int> mp;for(int i = 19;i > 0;--i){if(!(status&(1<<i))) continue;int j = i-1;for(;j >= 0;--j)if(!(status&(1<<j)))break;if(j == -1) continue;mp[grundy(status ^ ((1<<i) + (1<<j)))] = 1;;}for(int i = 0;;i++){if(!mp[i])return sg[status] = i;} } int main(){cin>>T;memset(sg,-1,sizeof(sg));while(T--){scanf("%d",&n);int ans = 0;for(int i = 1;i <= n;++i){scanf("%d",&m);int status = 0;for(int j = 1;j <= m;++j){int p;scanf("%d",&p);status |= 1<<(20-p);}ans ^= grundy(status);}if(ans) puts("YES");else puts("NO");}return 0; }

總結

以上是生活随笔為你收集整理的闲来无事刷水题、简单博弈论专题、sg函数、洛谷的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。