字符串DP cf803E

来源:互联网 发布:长期避孕药 知乎 编辑:程序博客网 时间:2024/06/07 17:21

http://codeforces.com/problemset/problem/803/E

状态表示

d[i][j],第i局得分为j是否成立

转移方程

  1. 这一局为?,即可能赢,输,平局:d[i][j]=d[i1][j1]|d[i1][j+1]|d[i1][j]
  2. 已经确定该局的状态,直接按照条件转移即可:
    a) ai=W:d[i][j]=d[i1][j1]
    b) ai=L:d[i][j]=d[i1][j+1]
    c) ai=D:d[i][j]=d[i1][j]

细节

  1. 注意可能最后得分是-k,所以在dp的时候,对j加上偏移量。
  2. 注意边界,在i<j一定不满足,并且j=k or j=k时,i必须为n
#include <bits/stdc++.h>using namespace std;const int M=1001;char s[1010];int f[1010][2010],g[1010][2010];int n,k;void dp(int i,int t){    for(int j=-k+1+M;j<M+k;j++)    {        if(!f[i][j]&&f[i+1][j+t])        {            f[i][j]=1;            g[i][j]=t;        }    }}int main(){scanf("%d%d%s", &n, &k, s);f[n][M+k]=f[n][M-k]=1;    for(int i=n-1;i>=0;i--)    {        if(s[i]=='W') dp(i,1);        else if(s[i]=='L') dp(i,-1);        else if(s[i]=='D') dp(i,0);        else dp(i,0),dp(i,1),dp(i,-1);    }    if(f[0][M])    {        for(int i=0,j=M;i<n;i++)        {            s[i]=(g[i][j]+1)["LDW"];            j+=g[i][j];        }        printf("%s\n",s);    }    else    {        printf("NO\n");    }return 0;}