ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)
Posted fht-litost
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)相关的知识,希望对你有一定的参考价值。
https://nanti.jisuanke.com/t/31454
题意
两个人玩游戏,最初数字为m,有n轮,每轮三个操作给出a b c,a>0表示可以让当前数字加上a,b>0表示可以让当前数字减去b,c=1表示可以让当前数字乘-1,数字范围为[-100, 100],如果加/减出范围则直接等于边界,最终结果数字x>=R则为Good Ending,x<=L则为Bad Ending,否则Normal Ending,第一个人希望好结局,第二个人希望坏结局,如果没有办法就希望平局,每个人都做最优选择。求最终结果
分析
一开始题目没看懂啊。。很蒙,然后学弟就秒了。
所以状态1000*200,考虑暴力求解。又是博弈题,那当然是记忆化搜索啦。把每个状态都搜一下,优先选赢,其次才是平局,最后才是输。
因为分数可能为负数,所以这里加了个115变成正数来计算,方便得多。
#include<bits/stdc++.h> using namespace std; #define LL long long #define mod 1000000007 int n, L, R, dp[1005][250]; typedef struct Res{ int x, y, z; }Res; Res 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 dfs(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){//先手,想造出GoodEnding if(s[id].x!=0){ temp = dfs(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 = dfs(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 = dfs(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 = dfs(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 = dfs(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 = dfs(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(i=1;i<=n;i++) scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].z); memset(dp, 62, sizeof(dp)); ans = dfs(1, m+115); if(ans==1) puts("Good Ending"); else if(ans==-1) puts("Bad Ending"); else puts("Normal Ending"); return 0; }
以上是关于ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)的主要内容,如果未能解决你的问题,请参考以下文章
ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)
ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)
ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(博弈,记忆化搜索)