博弈论之威佐夫博弈篇(poj1067)

博弈论之威佐夫博弈篇(poj1067)

(简单看了一下poj上的通过率和内容之后选了这道题做,毕竟是为了练习Java?就不要选太复杂的了,手动狗头。)

博弈论

鉴于水平有限,就不给大家放一些概念性的东西了,可以自己百度。我理解的博弈论就是两个人之间进行公平对决都采用最优策略轮流对抗,直到分出胜负。

威佐夫博弈

有两堆各若干个物品,两个人轮流从任一堆取至少一个或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

poj1067这道题要求解的是先手的胜负。
这题拿到手之后感觉有点懵,然后凭着之前的一丢丢经验,开始思考,先手胜分两种情况:一种是两堆物品数量相同时,即(n,n),另一种是一堆被取光,另一堆还有物品。然后从小规模问题开始分析:1,0时必胜,1,1时必胜,1,2时必败。但是还是没有思路,然后去看了别人的题解,发现可以套公式,然后就很简单了。
请忽略上一段话,以下才是正文部分。
首先来介绍一下奇异局势
我们用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,…,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。
两个人如果都采用正确操作,那么面对非奇异局势,先拿者必胜;反之,则后拿者取胜。简单来说奇异局势在这道题中就是甲的必败态。
奇异局势的性质:
1.任何自然数都包含在一个且仅有一个奇异局势中。
由于a[k]是未在前面出现过的最小自然数,所以有a[k] > a[k-1] ,而 b[k]= a[k] + k > a[k-1] + k > a[k-1] + k - 1 = b[k-1] > a[k-1] 。所以性质1成立。
2.任意操作都可将奇异局势变为非奇异局势。
3.采用适当的方法,可以将非奇异局势变为奇异局势。
奇异局势公式:
a[k]=m*(1+√5)/2 b[k]=a[k]+m;
然后可以可以套用公式,对于局势(x,y),x<y,如果(y-x)*(√5+1)/2=x,,那么这个局势(x,y)就是一个奇异局势,先手必败。反之先手有必胜策略。
C++代码
#include<iostream>
#include<math.h>
using namespace std;

int main(void)
{
	int m,n,temp;
	while((cin>>m>>n)!=0)
	{
		if(m>n)
			swap(m,n);
		if(floor((n-m)*((1+sqrt(5))/2))==m)
			cout<<0;
		else cout<<1;
	}
	return 0;
}
java代码
import java.util.*;
import java.lang.*;

class Main
{  
    public static void main(String args[])
    {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext())
		{
			int m=sc.nextInt();
			int n=sc.nextInt();
			int temp;
			if(m>n)
			{
				temp=m;
				m=n;
				n=temp;
			}
			if(Math.floor((n-m)*(Math.sqrt(5.0)+1)/2)==m)
			   System.out.println(0);
			else 
			   System.out.println(1);
		}
    }
}
1 sqrt(5) dev不会报错,但是oj判的时候就编译错误了,最好养成习惯写成float或double类型
2 第一次用java在oj上交题。 类要写成Main
输入:while(sc.hasNext()) {}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值