博弈论
图一乐图一乐
这个作者很懒,什么都没留下…
展开
-
Coin Game HDU - 3951(博弈思维)
题意:给一个由非零自然数组成的环,每次可取1~k个连续数字,最后可取得人赢。对称性博弈,后手能对先手做复制操作。int main(){ int n, k; cin >> t; int c = 0; while (t--) { scanf("%d%d", &n, &k); printf("Case %d: ", ++c); if (k >=...原创 2020-03-25 22:06:11 · 82 阅读 · 0 评论 -
A Multiplication Game HDU - 1517(SG函数打表找规律)
首先,这道题的SG函数很好写,举个例子:n=17,那么17/2=8.5,这时的出边可以是9,因为要找的是p>=n,那么2*9=18是可以的情况,所以用ceil上取整就好了。附上SG打表代码:int fg[1000];int sg(int x){ if (fg[x] != -1)return fg[x]; unordered_set<int> st; f(i, 2, ...原创 2020-03-24 20:11:58 · 139 阅读 · 0 评论 -
取(2堆)石子游戏 HDU - 2177(威佐夫博弈)
double eqa = ( 1+sqrt(5.0)) / 2.0;int main(){ int n, m; while (cin >> n >> m) { if (n == 0 && m == 0)break; if (n > m)swap(n, m); if ((int)((m - n)*eqa) == n) { puts(...原创 2020-03-24 14:34:43 · 178 阅读 · 0 评论 -
取石子游戏 HDU - 1527(威佐夫博弈)
威佐夫博弈:给两堆石子,有两种操作,在一堆取任意多,在两堆取相同数量。规律:求差值,如果差值*黄金分割数==较小的数,那么先手必败。double eqa = ( 1+sqrt(5.0)) / 2.0;int main(){ int n, m; while (~scanf("%d%d", &n, &m)) { if (n > m)swap(n, m); i...原创 2020-03-24 13:27:18 · 155 阅读 · 0 评论 -
取(m堆)石子游戏 HDU - 2176
int a[N];int main(){ int m; while (cin >> m && m) { int ans = 0; f(i, 1, m) { scanf("%d", &a[i]);ans ^= a[i]; } if (ans == 0) { puts("No");continue; } puts("Yes"); uno...原创 2020-03-24 09:07:32 · 74 阅读 · 0 评论 -
Being a Good Boy in Spring Festival(尼姆博弈)
尼姆博弈:a[1]^a[2]…a[m]=0(先手必败)a[1]^a[2]…a[m]=x!=0(先手必胜)假设x的2进制中1最高位在第k位,那么a[1]…a[m]至少存在一个数它的2进制中1最高位在第k位。于此同时a[?]^x<a[?](最高位1变成0了)用a[?]^x代替a[?]是可行的,那么右边变成了:x ^ x=0(留给对手必败态)int a[105];int main()...原创 2020-03-23 15:56:34 · 133 阅读 · 0 评论 -
Game HDU - 3389(阶梯博弈,找规律)
const int N = 1e6 + 5;int t;int main(){ int c = 0,n,x; cin >> t; while (t--) { cin >> n; int ans = 0; f(i, 1, n) { scanf("%d", &x); if (i % 6 == 2 || i % 6 == 5 |...原创 2020-03-08 21:19:51 · 125 阅读 · 0 评论 -
Nim or not Nim? HDU - 3032(sg函数找规律)
给两种操作:1.选一堆石子,假设堆中有x个,从中取[0,x-1]个 。2.将一堆石子拆成两堆小的,两堆小的数量加起来等于分离前。数据达到了1e6,而这里的sg函数比较好写,打个表,看看sg值规律,发现模4余3的sg(x)=x+1,模4余0的sg(x)=x-1,其他不变const int N = 1e6 + 5;int t;/*int fg[1000];int sg(int x){...原创 2020-03-08 20:33:58 · 114 阅读 · 0 评论 -
邂逅明下 HDU - 2897(sg函数打表,巴什博奕)
1.很明显,题目给出一个区间,求一堆的结果 ,所以肯定跟巴什博奕有关,也就是跟n%周期(l+r)有关2.但有一个很不一样的地方,这里最后取的人是输,如果直接想可能有点难想,还会想错,所以用sg函数打个表看看结果与余数之间的关系int n, r, l;/*int fg[1010];int sg(int x){ if (fg[x] != -1)return fg[x]; unordere...原创 2020-03-08 19:28:46 · 242 阅读 · 0 评论 -
Good Luck in CET-4 Everybody! HDU - 1847(sg函数,集合尼姆博弈)
典型的集合尼姆博弈,而且这里只有一张图,遍历出边进行mex求sg值int n, m;int fg[1010];int op[11] = { 0,1,2,4,8,16,32,64,128,256,512 };int sg(int x){ if (fg[x] != -1)return fg[x]; unordered_set<int> s; f(i, 1, 10)//拓展出...原创 2020-03-08 15:46:47 · 75 阅读 · 0 评论 -
Brave Game HDU - 1846(巴什博奕,区间的博弈)
问题:给一堆石子,每次能去[1,m]个,问先手是否win。开始做时并不知道巴什博奕,硬用一堆的集合尼姆博弈去理解。后来百科了之后就懂了,假设n=m+1,那么无论第一个人取多少,余下的第二人都能一次取完。拓展一下n=a(m+1)+b,那么第一个人只需要第一次取b个,之后如果第二个人取k个,那第一个就取(m+1-k)个,一直保持取完后是(m+1)的倍数,第一个人就赢了。再拓展一下,如果区间是[...原创 2020-03-08 14:57:43 · 147 阅读 · 0 评论 -
Euclid's Game HDU - 1525
思路:分析x与y大小关系与结果之间的联系(这里x是max(x,y))1.x==y,先手赢2.x>=2y,由于结果开始就是确定的 ,而x>=2y时,例如:x=9,y=4,必然可以得到结果相反的情况,如 x=5,y=4和x=1,y=4int play(int x,int y){ if (x == y || x >= 2 * y)return 0; else return ...原创 2020-03-08 13:56:08 · 72 阅读 · 0 评论 -
AcWing 1319. 移棋子游戏
sg函数是一张有向无环图尼姆博弈对每一张图sg(值)进行游戏就是加强版的集合尼姆博弈(集合尼姆博弈中拓展是根据集合可能的新状态),这里是回归本质,sg操作是对每个状态拓展出边,并通过出边sg值集合进行mex操作,来求当前点的sg值vector<int>G[2005];int fg[2005];int n, m, k, x,y;int sg(int x){ if (fg[...原创 2020-03-07 12:05:40 · 265 阅读 · 0 评论 -
AcWing 894. 拆分-Nim游戏
理解:一个局面的sg值等于形成它的子局面的异或。int fg[110];int sg(int x){ if (fg[x] != -1)return fg[x]; unordered_set<int> s; f(i, 0, x - 1)//遍历半角矩阵 f(j, i, x - 1) s.insert(sg(i) ^ sg(j));//一个新局面的sg值等于子局面的异或...原创 2020-03-07 11:21:03 · 104 阅读 · 0 评论 -
Acwing 893. 集合-Nim游戏
一直在用考的少的理由,不学博弈论(game)。不学还是不行啊,先学个sg记忆化状态1.sg()函数是递归求解某个状态sg值的过程,fg[]用来记忆化。2.每个sg函数可以理解为一张有向无环图,每次遍历他的出边3.求出每个堆的sg值后,再用尼姆博弈基本定理。int s[105], fg[10010];int n, m;int sg(int x){ if (fg[x] != -1)re...原创 2020-03-06 23:21:31 · 195 阅读 · 0 评论