2019年FJNU低編賽 G題(dfs博弈)

###題目連接###php

 

題目大意:ios

有一個 0 ~ n+1 的數軸,Alice 站在 0 點處,Bob 站在 n+1 點處。在 1 ~ n 上各有着權值。 Alice 每次向右移動 1 格或兩格 ,Bob 每次向左移動 1 格或 2 格(他們必定要移動),Alice 移動到 n+1 處中止,Bob 移動到 0 處中止,直到他們都中止的時候,此時若 Alice 所通過的數值總和大於 Bob 的數值總和,則 Alice 勝出,反則 Bob 勝出。Alice 先出手,兩人足夠聰明,走到的數值必須拿走,而走到過的數值不能再被拿走。spa

 

分析:code

一、顯然是博弈題。blog

二、dfs 枚舉全部可能,當 Alice 出手時,有兩種走法(走一步或兩步)。好比 Alice 走一步後,枚舉 Bob 走到的地方(也只有兩種走法),而後判斷是否 Bob 不管怎樣走, 此時 Alice 必贏,則 「此刻 Alice 走一步」 爲必勝態,由於若 Alice 走這一步以後, Bob 不管怎麼操做都沒法獲勝,則此時爲必勝態。get

三、故枚舉 Alice 的兩次走法,假如此時 Alice 處於位置 x ,若此刻走到 u 可使得自身處於必勝態,則返回 true ,告訴 dfs 的上一層中,走到 x 處能夠轉化爲必勝態。string

 

博弈點分析:假如此刻位置爲 x ,如今兩種走法可使得 x 走到 u1 或者 u2。若 u1 與 u2 同時爲必勝點,則 x 處也爲必勝點;若 u1 是必勝點,u2 是必敗點,則 x 處也爲必勝點,由於 選手足夠聰明,走到 x 處後會走到 u1 處,故 x 爲必勝點;若 u1 與 u2 同爲必敗點,則 x 也爲必敗點。這就是爲何 必勝點能夠轉化爲必敗點或必勝點,而必敗點只能轉化爲必敗點。it

 

細節處理:io

一、此題不該該 vis 設爲 bool 類型,由於走過的點會重複,很差判斷。class

二、最好走到臨界點的時候特判(x==n+1 以及 y==0)。

 

代碼以下:

 

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int t,n;
int a[18];
int tox[2]={1,2};
int toy[2]={-1,-2};
int vis[18];
bool dfs(int x,int y,int res,int ans){
    if(x==n+1&&y==0) return res>ans;
    bool q;
    for(int i=0;i<2;i++){
        q=true;
        int u,res1;
        if(x==n+1) u=x,res1=0;
        else{
            u=x+tox[i];
            if(u>n+1) continue;
            vis[u]++;
            res1=(vis[u]==2?0:a[u]);
        }
        for(int j=0;j<2;j++){
            int v,ans1;
            if(y==0) v=y,ans1=0;
            else{
                v=y+toy[j];
                if(v<0) continue;
                vis[v]++;
                ans1=(vis[v]==2?0:a[v]);
            }
            bool w=dfs(u,v,res+res1,ans+ans1);
            if(y!=0) vis[v]--;
            if(!w) {
                q=false;
                break;
            }
        }
        if(x!=n+1) vis[u]--;
        if(q) return true;
    }
    return false;
}
int main()
{
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        a[0]=a[n+1]=0;
        if(dfs(0,n+1,0,0)) printf("Alice\n");
        else printf("Bob\n");
    }
}
相關文章
相關標籤/搜索