ACM-ICPC 2018 徐州賽區網路預賽
阿新 • • 發佈:2018-12-09
題意:
每一輪有三種操作, 加上a 減去b 或者 取負 當且僅當 a, b, c 不為0時,對應的操作有效; 給出一個上界和一個下界 大於等於上界就是 Good Ending 小於等於下界 就是 Bad Ending 否則就是 Normal Ending 兩個人輪流操作,第一個人想要Good Ending 第二個人想要 Bad Ending 兩個人操作最優,求最後的結局
思路:
dp[i][j] 表示 第幾輪 數字是多少的時候 ,記憶化爆搜 ,因為數字在[−100,100]
#include<bits/stdc++.h> using namespace std; const int maxn=1e3+7; int n,m,k,l,a[maxn],b[maxn],c[maxn]; int dp[maxn][250];//dp[i][id[j]]表示第i輪的數字為j map<int,int> id; int up,down; int dfs(int pos,int now) { if(pos==n+1) { if(now>=k) return 2; else if(now>l) return 1; else return 0; } if(dp[pos][id[now]]!=-1) return dp[pos][id[now]]; if(pos&1)//奇數 { int f=0; if(a[pos]) f=max(f,dfs(pos+1,min(now+a[pos],up))); if(b[pos]) f=max(f,dfs(pos+1,max(now+b[pos],down))); if(c[pos]) f=max(f,dfs(pos+1,-now)); return dp[pos][id[now]]=f; }else{ int f=2; if(a[pos]) f=min(f,dfs(pos+1,min(now+a[pos],up))); if(b[pos]) f=min(f,dfs(pos+1,max(now+b[pos],down))); if(c[pos]) f=min(f,dfs(pos+1,-now)); return dp[pos][id[now]]=f; } } int main() { int tot=0; up=100; down=-100; for(int i=-100;i<=100;i++) id[i]=++tot; scanf("%d%d%d%d",&n,&m,&k,&l); for(int i=1;i<=n;i++) { scanf("%d%d%d",&a[i],&b[i],&c[i]); b[i]=-b[i]; } memset(dp,-1,sizeof dp); int f=dfs(1,m); if(f==2) printf("Good Ending\n"); else if(f==1) printf("Normal Ending\n"); else printf("Bad Ending\n"); return 0; }