版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/PK__PK/article/details/82728296
题目链接:https://nanti.jisuanke.com/t/31454
题意:两个人玩游戏,轮流操作,每次操作有三个选项,当前值+x,当前值-x,当前值变成相反数。然后还有一个区间【L,R】,若第最后得分大于等于R,第一个人赢,小于等于L 第二个人赢。否则平局。问最后谁获胜。
题解:记忆化搜索。定义dp【i】【j】为第 i 轮等分为 j 的胜负状况。然后看代码即可
#include<bits/stdc++.h>
using namespace std;
int n,L,R,dp[1005][250];
struct res{
int x,y,z;
}s[1005];
int Go(int x,int y,int t = 0){
if(x == 1) y = min(y+t,215);
else if(x == 2) y = max(y-t,15);
else y += 2*(115-y);
return y;
}
int Sech(int id,int x){
int win,lose,done,temp;
if(dp[id][x] <= 1)
return dp[id][x];
if(id == n+1){
if(x >= R) return 1;
if(x <= L) return -1;
return 0;
}
win = lose = done = 0;
if(id%2){
if(s[id].x != 0){
temp = Sech(id+1,Go(1,x,s[id].x));
if(temp == 1) win = 1;
if(temp == 0) done = 1;
if(temp == -1) lose = 1;
}
if(s[id].y != 0){
temp = Sech(id+1,Go(2,x,s[id].y));
if(temp == 1) win = 1;
if(temp == 0) done = 1;
if(temp == -1) lose = 1;
}
if(s[id].z != 0){
temp = Sech(id+1,Go(3,x));
if(temp == 1) win = 1;
if(temp == 0) done = 1;
if(temp == -1) lose = 1;
}
if(win) return dp[id][x] = 1;
else if(done) return dp[id][x] = 0;
else return dp[id][x] = -1;
}
else {
if(s[id].x != 0){
temp = Sech(id+1,Go(1,x,s[id].x));
if(temp == 1) lose = 1;
if(temp == 0) done = 1;
if(temp == -1) win = 1;
}
if(s[id].y != 0){
temp = Sech(id+1,Go(2,x,s[id].y));
if(temp == 1) lose = 1;
if(temp == 0) done = 1;
if(temp == -1) win = 1;
}
if(s[id].z != 0){
temp = Sech(id+1,Go(3,x));
if(temp == 1) lose = 1;
if(temp == 0) done = 1;
if(temp == -1) win = 1;
}
if(win) return dp[id][x] = -1;
else if(done) return dp[id][x] = 0;
else return dp[id][x] = 1;
}
}
int main(){
int ans,m,i;
scanf("%d%d%d%d",&n,&m,&R,&L);
R += 115;
L += 115;
for(int i = 1 ; i <= n ; i ++)
scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].z);
memset(dp,62,sizeof(dp));
ans = Sech(1,m+115);
if(ans==1)
printf("Good Ending\n");
else if(ans==-1)
printf("Bad Ending\n");
else
printf("Normal Ending\n");
return 0;
}