AcWing ---- 893。Set-Nim Game(Java)_Mathematics_Game Theory_SG Function_MexOperation_N図

オリジナルタイトルリンク

①。タイトル

ここに画像の説明を挿入

②。考える

ここに画像の説明を挿入

Mex运算

  • Sが非負の整数のセットを表すとします。mex(S)を定義して、セットSに属さない最小の非負の整数演算を見つけます。つまり:mes(S)= min(x);例:S =(0,1,2、4)、次にmes(S)= 3

SG函数:

  • 有向グラフゲームでは、ノードxごとに、xから始まりノードy1、y2、... ykに到達する合計k個の有向エッジがあり、SG(x)のポストスクリプトノードy1、y2、...を定義します。 ···。ykのSG関数値のセットに対してmex操作を実行した結果SG(x)=mex({SG(y1),SG(y2)····SG(yk)})特に、有向グラフゲームG全体のSG関数値は、有向グラフゲームの開始点sのSG関数値、すなわち、SG(G)= SG(s)として定義される。

有向图游戏的和

  • 有向グラフゲームの合計のSG関数値は、それに含まれる各サブゲームのSG関数のXOR合計に等しくなります。
    SG(G)=SG(G1)xorSG(G2)xor···xor SG(Gm)

ここに画像の説明を挿入

ここに画像の説明を挿入

③。学習ポイント

博弈论

④。コードの実装

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;

public class Main {
    
    
	static int M=110,N=10010,k;
	static int s[]=new int[M]; //存放集合的中元素
	static int sg[]=new int[N]; //存放某个数的SG函数的值
	public static void main(String[] args) {
    
    
		Arrays.fill(sg, -1);
		Scanner sc = new Scanner(System.in);
		k=sc.nextInt();
		for (int i = 0; i <k; i++) {
    
    
			s[i]=sc.nextInt();
		}
		int n=sc.nextInt();
		int res=0;
		while(n-->0) {
    
    
			int x=sc.nextInt();
			//直接异或sg函数的和 进行判断
			res^=sg(x);
		}
		System.out.println(res!=0?"Yes":"No");
	}
	
	//递归sg 有点难搞 debug看看
	static int sg(int x) {
    
    
		if(sg[x]!=-1) return sg[x]; //若sg存在直接返回出来
		//每次递归重新创建一个set集合
		HashSet set = new HashSet<>();
		//枚举集合中每一个数 进行比较
		for (int i = 0; i <k; i++) {
    
    
			if(x>=s[i]) {
    
    
				set.add(sg(x-s[i])); //递归往set集合中添加sg函数
			}
		}
		//在集合中找,最小的不存在的值
		for (int i = 0; i <=N; i++) {
    
    
			if(!set.contains(i)) {
    
    
				return sg[x]=i;//找到,保存,返回
			}
		}
		return 0;
	}
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_45480785/article/details/114105054