BE, GE or NE 2018徐州网络赛B题

BE, GE or NE 2018徐州网络赛B题

题目大意:
有A和B两个人,有一个初始分数m,A与B会进行n次操作,每次操作可以让一个数乘-1,或加x,或减x,A想让分数尽量打,B想让分数尽量小。问最后结果
分析:
用记忆化搜索来解决博弈问题

**#include <iostream>
#include 
#include  
#include 
#include 
using namespace std;
const int maxn = 1000 + 10;
int dp[maxn][210];
int n,m,k,l;
int a[maxn],b[maxn],c[maxn];
int dfs(int now,int num,int u)
{
   // cout<
    if(num>=200) num=200;
    if(num<0)    num=0;
    if(now==n+1)
    {
        return num;
    }
    if(dp[now][num]!=-1) return dp[now][num];
    int x,y,z;
    if(u%2)
    {
        if(a[now]) dp[now][num]=max(dp[now][num],dfs(now+1,num+a[now],1-u));
        if(b[now]) dp[now][num]=max(dp[now][num],dfs(now+1,num-b[now],1-u));
        if(c[now]) dp[now][num]=max(dp[now][num],dfs(now+1,200-num,1-u));
    }
    else
    {
        dp[now][num]=0x3f3f3f3f;
        if(a[now]) dp[now][num]=min(dp[now][num],dfs(now+1,num+a[now],1-u));
        if(b[now]) dp[now][num]=min(dp[now][num],dfs(now+1,num-b[now],1-u));
        if(c[now]) dp[now][num]=min(dp[now][num],dfs(now+1,200-num,1-u));
    }
    return dp[now][num];
}
int main() {
    while(~scanf("%d%d%d%d",&n,&m,&k,&l))
    {
        m+=100;
        k+=100;
        l+=100;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d",&a[i],&b[i],&c[i]);
        }
        memset(dp,-1,sizeof(dp));
        int ans=dfs(1,m,1);
     //   cout<
        if(ans>=k) puts("Good Ending");
        else if(ans<=l) puts("Bad Ending");
        else           puts("Normal Ending");
    }
    return 0;
}**

你可能感兴趣的:(博弈)