题目链接
http://codeforces.com/contest/803/problem/E
思路
dp
状态表示
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 <script type="math/tex" id="MathJax-Element-579">n</script>。
代码
#include <bits/stdc++.h>
using namespace std;
inline int in() {int x; scanf("%d", &x); return x;}
#define pr(x) {cout << #x << ' ' << x << endl;}
const int maxn = 1000 + 5;
const int off = 2000;
int d[maxn][maxn + off], n, k;
char a[maxn];
int dfs(int i, int j) {
if (i == 0) return d[i][j + off] = j ? 0 : 1;
if (d[i][j + off] != -1) return d[i][j + off];
if (i < j || (i != n && (j == k || j == -k))) return d[i][j + off] = 0;
int ans = 0;
if (a[i] == 'W') ans |= dfs(i - 1, j - 1);
else if (a[i] == 'L') ans |= dfs(i - 1, j + 1);
else if (a[i] == 'D') ans |= dfs(i - 1, j);
else ans = dfs(i - 1, j - 1) | dfs(i - 1, j + 1) | dfs(i - 1, j);
return d[i][j + off] = ans;
}
void FindPath(int i, int j) {
if (i == 0) return;
int ans = (a[i] == '?' ? (d[i - 1][j + 1 + off] ? 1 : (d[i - 1][j - 1 + off] ? -1 : 0)) : (a[i] == 'W' ? -1 : (a[i] == 'L' ? 1 : 0)));
FindPath(i - 1, j + ans);
if (ans == 1) cout << 'L';
else if (ans == -1) cout << 'W';
else cout << 'D';
}
int main() {
n = in(), k = in();
getchar();
for (int i = 1; i <= n; i++) scanf("%c", &a[i]);
memset(d, -1, sizeof(d));
int ans = dfs(n, k);
if (ans) {
FindPath(n, k);
} else {
memset(d, -1, sizeof(d));
ans = dfs(n, -k);
if (ans) FindPath(n, -k);
else cout << "NO" << endl;
}
return 0;
}