ACM - 暑期第六天:博弈论

1.博弈论原理

博弈论是二人或多人在平等的对局中各自利用对方的策略变换自己的对抗策略,达到取胜目标的理论。博弈论是研究互动决策的理论。博弈可以分析自己与对手的利弊关系,从而确立自己在博弈中的优势,因此有不少博弈理论,可以帮助对弈者分析局势,从而采取相应策略,最终达到取胜的目的。


初时不明就里,了解了原理后才发现和初一玩的报数原理一样。两个同学玩报数游戏,从一报道二十,加一或者加二,一直累加,最后加到二十那个人获胜。



2.解决方法

下面介绍分析此类题目的通用方法:P/N分析:

P点: 即必败点,某玩家位于此点,只要对方无失误,则必败;

N点: 即必胜点,某玩家位于此点,只要自己无失误,则必胜。

三个定理:

    一、 所有终结点都是必败点P(上游戏中,轮到谁拿牌,还剩0张牌的时候,此人就输了,因为无牌可取);

    二、所有一步能走到必败点P的就是N点;

    三、通过一步操作只能到N点的就是P点;


所有博弈论算法都是根据上面的三条原理推论出来的。(是不是从上面三条原理看不出什么东东~~我也是啊~)博弈论关键是从后面找出必败点(终结点)的规律。其实在确定谁先谁后的时候利用博弈论原理就能确定谁胜谁负了,所以做题目旨在找出必败点(终结点)的变化规律并用数字表示出来。


题目链接:农大1212博弈论题目


第一种解法:

//fafu1212 博弈论
#include <stdio.h>
#include <string.h>

const int maxn = 33;
__int64 p[maxn];
int m, n;

void init()
{
	memset(p, 0, sizeof(p));
	p[0] = 0;
	p[1] = 2;
	for(int i = 2; i < maxn; i++)
	{
		p[i] = 2 * p[i - 1] + 2;
	}
}
bool search(int cas)
{
	for(int i = 0; i < maxn; i++)
		if(p[i] == cas)
			return false;
	return true;
}
int main()
{
	init();
	scanf("%d", &m);
	while(m--)
	{
		scanf("%d", &n);
		if(search(n))
			puts("Johvid");
		else puts("Abby");
	}
	return 0;
}

第二种解法(神人之作):


#include <stdio.h>

int cas, n;
int main()
{
    scanf("%d", &cas);
    while(cas--)
    {
        scanf("%d", &n);
        puts((n + 1) & (n + 2)? "Johvid" : "Abby");
    }
    return 0;
}


题目链接:杭电2147博弈论题目


解法:

#include <stdio.h>

int n, m;

int main()
{
	while(scanf("%d%d", &n, &m), n || m)
	{
		puts((n & 1) && (m & 1)? "What a pity!" : "Wonderful!");
	}
	return 0;
}



3.总结及计划

明天的计划:开始图论之旅,图论看Z君的博客。

今天的总结:一 . 看到Z君的博客上的省赛总结,做400+的题目,数学思维没有提高的话,只是一个打酱油的。今后要兼顾数学思维。数学是一切科学的源头!

二 . Z君在博客上提到的,该会的题目会,不该会的题目一直不会,我现在也陷入这种尴尬的局况了,就像学动态规划时,看来两三次都看不懂。各种无奈。~~~~但是~~~~真正的夕阳武士就是明知不可为而为之。这边找了几个原因:1. 不该会的一直学不会没有人指导,自己懒。2. 没有狠狠地训练几题相关的题目。各个突破,自学最重要,图论学完把动态规划再用心学一遍,题目做个十几道。


你可能感兴趣的:(ACM,博弈论,杭电2147,农大1212)