codeforces 803e
题意:W表示A赢,L表示输,D表示平局,?表示不确定,当净胜或净输达到k的时候游戏结束,已知n轮后游戏结束,现在给出n轮的胜负,?表示未知,确定?的情况,使得在n轮之后游戏结束
思路:1、将胜看作1 负为-1 平局为0,净胜即为前缀和, dp[i][j]表示前i轮净胜为j是否可能 。
2、也可以记忆化搜索,dfs(u,v) 表示第u位前缀和为v , 每次搜索完一位后标记起f[u][v]来,如果第一次dfs(u,v)不可行的话,后面再次dfs(u,v)也一定不可行,如果第一次可行的话,那么不会再次出现dfs(u,v) ,后面相同的情况直接return 0;
AC代码:
#include "iostream" #include "iomanip" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #pragma comment(linker, "/STACK:102400000,102400000") #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a,x) memset(a,x,sizeof(a)) #define step(x) fixed<< setprecision(x)<< #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define ll long long #define endl ("\n") #define ft first #define sd second #define lrt (rt<<1) #define rrt (rt<<1|1) using namespace std; const ll mod=1e9+7; const ll INF = 1e18+1LL; const int inf = 1e9+1e8; const double PI=acos(-1.0); const int N=1e5+100; const int O=1005; int n,k,dp[1005][2005],a[1005],load[1005][2005],ans[1005]; char s[105],as[4]={'L','D','W'}; int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>k>>s; for(int i=0; i<n; ++i){ if(s[i]=='W') a[i+1]=1; else if(s[i]=='L') a[i+1]=-1; else if(s[i]=='D') a[i+1]=0; else a[i+1]=6; } for(int i=1,sum=0; i<=n; ++i){ if(a[i]==6) break; sum+=a[i]; if(sum==k && sum==-k){ cout<<"NO"; return 0; } } dp[0][0+O]=1; for(int i=1; i<=n; ++i){ for(int j=-k-1+O; j<k+O; ++j){ if(dp[i-1][j]==0) continue; if(i==n){ if(a[i]==6){ dp[i][j]=1, load[i][j]=0; dp[i][j-1]=1, load[i][j-1]=-1; dp[i][j+1]=1, load[i][j+1]=1; } else dp[i][j+a[i]]=1, load[i][j+a[i]]=a[i]; } else{ if(a[i]==6){ dp[i][j]=1, load[i][j]=0;; if(j-1-O>-k) dp[i][j-1]=1, load[i][j-1]=-1; if(j+1-O<k) dp[i][j+1]=1, load[i][j+1]=1; } else if(j+a[i]-O<k && j+a[i]-O>-k) dp[i][j+a[i]]=1, load[i][j+a[i]]=a[i]; } } } if(!dp[n][k+O] && !dp[n][-k+O]){ cout<<"NO"; return 0; } int now; if(dp[n][k+O]==1) now=k+O, ans[n]=1; else now=-k+O, ans[n]=-1; for(int i=n; i>=1; --i){ //cout<<now<<endl; ans[i]=load[i][now]; now-=load[i][now]; } for(int i=1; i<=n; ++i){ cout<<as[ans[i]+1]; } return 0; }
记忆化搜索:
#include<bits/stdc++.h> using namespace std; int n,k; string s; bool dp[1010][1010]; bool dfs(int u,int v){ if(u==n&&abs(v)==k)return 1; if(u==n||abs(v)>=k)return 0; if(dp[u][v])return 0; dp[u][v]=1; if(s[u]=='W')return dfs(u+1,v+1); if(s[u]=='D')return dfs(u+1,v); if(s[u]=='L')return dfs(u+1,v-1); if(dfs(u+1,v+1)){s[u]='W';return 1;} if(dfs(u+1,v)){s[u]='D';return 1;} if(dfs(u+1,v-1)){s[u]='L';return 1;} return 0; } int main(){ cin>>n>>k;cin>>s; if(!dfs(0,0))puts("NO"); else cout<<s<<endl; }