surreal number(不平衡博弈的一类解决方法)

近期复习博弈论,以前一直不会surreal number。现在回去看了看,利用几篇博客:
博客
国家队论文
初步了解了surreal num(超实数),大概可以用来解决一些较裸的不平等博弈的题目(=,=)
总结一下:
关于surreal number的概念论文讲的很清楚,相关性质以及运算都有很好的介绍。不再赘述。讲一下如何运用这个定理做题。
首先得到了surreal number(设为x,L玩家状态为正值状态,R玩家相反)之后就可以直接来判胜负了。

  1. x>0,则无论L玩家先手后手,他必胜
  2. x<0,则无论R玩家先手后手,他必胜
  3. x=0,则谁后手谁必胜

而多个独立游戏的surreal number则为他们的和(就是单纯和的意思),而surreal number可以由下面的达利函数得出

surreal number(不平衡博弈的一类解决方法)_第1张图片
具体一些例子 { | }=0,{1| } = 2,{2| } = 3,{ |-1} = -2, { |-2} = -3,{1|2} = 1/2
两个比较重要的定理
surreal number(不平衡博弈的一类解决方法)_第2张图片
得到这些之后我们就可以来做这个模板题

题意,给出两组分别有3个不公平组合游戏的局面,比较这两个局面的surreal number的大小

具体做法集训队论文讲的很清楚,需要注意的是,我们处理分数会有误差,所以我们将他们乘上一个2的幂次都化成整数比较

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring> 
#define ll long long 
using namespace std;
int len[5];
ll a[5][105];
ll getsrn(){
	for(int i=0;i<3;i++)scanf("%d",&len[i]);
	ll ret=0;
	for(int i=0;i<3;i++){
		for(int j=0;j<len[i];j++){
			char tmp[5];scanf("%s",tmp);
			if(tmp[0]=='B'){
				a[i][j]=-1;
			}else{
				a[i][j]=1;
			}
		}
	}
	for(int i=0;i<3;i++)
	{
		ll c = (1ll<<52);
		int j=0;while(j<len[i]&&a[i][j]==a[i][0])j++;
		ret+=a[i][0]*j*c;
		c>>=1;
		for(int k=j;k<len[i];k++){
			ret+= a[i][k]*c;
			c>>=1;
		}
	}
	return ret;
}
char s[100];
int kase;
int main(){
	int T;scanf("%d",&T);
	while(T--){
		scanf("%s%d",s,&kase);
		ll a1 = getsrn();
		ll a2 = getsrn();
		printf("%s %d: %s\n",s,kase,a1>=a2?"Yes":"No");
	}
	return 0;
}

你可能感兴趣的:(博弈)