我是靠谱客的博主 纯情眼睛,最近开发中收集的这篇文章主要介绍【博弈论】斐波那契博弈斐波那契博弈例题尝试推广,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

斐波那契博弈

简介

一堆有 n n n个物品,如果有甲乙两个人。甲和乙轮流从这对物品中选取物品,第一次可以取 1 ∼ n − 1 1sim n-1 1n1个物品,后一个人能取的物品数范围是 1 1 1到前一个人取的物品数 2 2 2倍,最后取光物品的人获胜。

思路

若甲先手,设当前物品数为 r r r

r ≤ 3 rle 3 r3时,甲无法取胜,甲必败。

r = 4 r=4 r=4时,甲取 1 1 1,乙剩 3 3 3个无法取胜,故甲必胜。

r = 5 r=5 r=5时,甲若取 2 2 2个及以上乙必胜。甲若取 1 1 1个,乙取 1 1 1个又变成了 r = 3 r=3 r=3的情况,乙胜。

根据上述过程,不难发现要想自己赢必须尽可能保证对方拿到斐波那契数。

也就是说,甲先手获胜需要满足 n n n不是斐波那契数。

算法模板

首先我们需要能计算斐波那契数

  1. 递归法
long long fib(int k){
    if(k<=1) return 1;
    else return fib(k-1)+fib(k-2);
}
  1. 递推法
long long fib(int k){
    fib[0]=fib[1]=1;
    for(int i=2;i<=k;i++){
        fib[i]=fib[i-1]+fib[i-2];
    }
    return fib[k];
}

模板

由于递推法的线性复杂度,所以采取递推来实现斐波那契博弈。

bool fibG(int n){//这里返回的是先手玩家是否可以获胜
    fib[0]=fib[1]=1;
    for(int i=2;fib[i-2]<=n;i++){
        if(fib[i-2]==n) return false;
        fib[i]=fib[i-1]+fib[i-2];
    }
    return true;
}

例题

hdu2516

大概概括一下,就是 n n n表示物品数,输出第一个人先手时哪个人能获胜,输出获胜的人(First win or Second win),输入 0 0 0表示结束。

#include <iostream>
using namespace std;
int fib[1001]; 
bool fibG(int n){//这里返回的是先手玩家是否可以获胜
    fib[0]=fib[1]=1;
    for(int i=2;fib[i-2]<=n;i++){
        if(fib[i-2]==n) return false;
        fib[i]=fib[i-1]+fib[i-2];
    }
    return true;
}
int main(){
    int n;
    while(cin>>n,n!=0){
        if(fibG(n)) cout<<"First winn";
        else cout<<"Second winn";
    }
    return 0;
}

尝试推广

如果规定先取完的人输,再看一下策略。

因为甲可以取 1 ∼ n − 1 1sim n-1 1n1个,那么甲直接取 n − 1 n-1 n1个,留下 1 1 1个给乙,则乙必输。

最后

以上就是纯情眼睛为你收集整理的【博弈论】斐波那契博弈斐波那契博弈例题尝试推广的全部内容,希望文章能够帮你解决【博弈论】斐波那契博弈斐波那契博弈例题尝试推广所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部