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;
}**
本文介绍了一种使用记忆化搜索解决两人博弈问题的方法。通过一个具体案例,详细展示了如何为两个试图最大化和最小化共同分数的玩家设计算法。文章提供了一个完整的C++代码示例,演示了递归函数如何根据当前状态和玩家选择来决定最优行动。

被折叠的 条评论
为什么被折叠?



