http://codeforces.com/problemset/problem/803/E
状态表示
d[i][j] ,第i局得分为j是否成立
转移方程
- 这一局为?,即可能赢,输,平局: d[i][j]=d[i−1][j−1]|d[i−1][j+1]|d[i−1][j]
- 已经确定该局的状态,直接按照条件转移即可:
a) ai=W:d[i][j]=d[i−1][j−1]
b) ai=L:d[i][j]=d[i−1][j+1]
c) ai=D:d[i][j]=d[i−1][j]
细节
- 注意可能最后得分是-k,所以在dp的时候,对j加上偏移量。
- 注意边界,在 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;
}