https://nanti.jisuanke.com/t/31454
记忆化搜索的博弈
看每个局面的所有子局面中 有负 则当前为胜 无负有平 则退而求其次 当前为平 当子局面中只有胜时 当前必负
#include <bits/stdc++.h>
using namespace std;
int dp[1010][210];
int a[1010],b[1010],c[1010];
int n,m,l,r;
int main()
{
int tmp[10];
int i,j,k,p,cnt,flag0,flag1,flag2;
scanf("%d%d%d%d",&n,&m,&r,&l);
for(i=1;i<=n;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]);
m+=100,l+=100,r+=100;
/*
for(j=0;j<=200;j++)
{
cnt=0;
if(a[n]>0)
{
p=min(j+a[n],200);
if(p>l) tmp[++cnt]=1;
else tmp[++cnt]=0;
}
if(b[n]>0)
{
p=max(j-b[n],0);
if(p>l) tmp[++cnt]=1;
else tmp[++cnt]=0;
}
if(c[n]>0)
{
p=-(j-100)+100;
if(p>l) tmp[++cnt]=1;
else tmp[++cnt]=0;
}
flag=0;
for(k=0;k<cnt;k++) if(tmp[k]==0) flag=1;
dp[n][j]=flag;
}
*/
if(n%2==0)//bad
{
for(j=0;j<=l;j++) dp[n+1][j]=0;
for(j=l+1;j<=r-1;j++) dp[n+1][j]=1;
for(j=r;j<=200;j++) dp[n+1][j]=2;
}
else
{
for(j=0;j<=l;j++) dp[n+1][j]=2;
for(j=l+1;j<=r-1;j++) dp[n+1][j]=1;
for(j=r;j<=200;j++) dp[n+1][j]=0;
}
for(i=n;i>=1;i--)
{
for(j=0;j<=200;j++)
{
cnt=0;
if(a[i]>0)
{
p=min(j+a[i],200);
tmp[++cnt]=dp[i+1][p];
}
if(b[i]>0)
{
p=max(j-b[i],0);
tmp[++cnt]=dp[i+1][p];
}
if(c[i]>0)
{
p=-(j-100)+100;
tmp[++cnt]=dp[i+1][p];
}
flag0=0,flag1=0,flag2=0;
for(k=1;k<=cnt;k++)
{
if(tmp[k]==0) flag2=1;
else if(tmp[k]==1) flag1=1;
else flag0=1;
}
if(flag2) dp[i][j]=2;
else if(flag1) dp[i][j]=1;
else dp[i][j]=0;
}
}
if(dp[1][m]==2) printf("Good Ending\n");
else if(dp[1][m]==1) printf("Normal Ending\n");
else printf("Bad Ending\n");
return 0;
}
/*
3 6 10 1
1 0 0
1 0 0
1 0 0
3 -5 5 -5
1 0 0
1 0 0
0 0 1
*/