BE, GE or NE ACM-ICPC 2018 徐州賽區網路預賽 (記憶化搜尋)
阿新 • • 發佈:2018-12-10
題意:兩個人玩遊戲,輪流操作,每次操作有三個選項,當前值+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; }