BE, GE or NE 2018徐州网络赛B题
题目大意:
有A和B两个人,有一个初始分数m,A与B会进行n次操作,每次操作可以让一个数乘-1,或加x,或减x,A想让分数尽量打,B想让分数尽量小。问最后结果
分析:
用记忆化搜索来解决博弈问题
**#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
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<<now<<" "<<num<<" "<<u<<endl;
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<<ans<<endl;
if(ans>=k) puts("Good Ending");
else if(ans<=l) puts("Bad Ending");
else puts("Normal Ending");
}
return 0;
}**