1. 程式人生 > >ACM-ICPC 2018 徐州賽區網絡預賽 B BE, GE or NE(記憶化搜索)

ACM-ICPC 2018 徐州賽區網絡預賽 B BE, GE or NE(記憶化搜索)

最優 n) long long struct mod 希望 code scanf color

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(記憶化搜索)