首页 > 代码库 > 803E

803E

dp

dp[i][j]表示到了i赢和输的差为j

如果这位是?向dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]转移,如果是W向dp[i-1][j-1]转移,如果是L向dp[i-1][j+1]转移,如果是D向dp[i-1][j]转移

技术分享
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, k;
char s[N], ans[N][N * 2];
int dp[N][N * 2], pre[N][N * 2];
int main()
{
    scanf("%d%d", &n, &k);
    scanf("%s", s + 1);
    dp[0][1000] = 1;
    for(int i = 1; i <= n; ++i)
        for(int j = -k + 1000; j <= k + 1000; ++j)
        {
            ans[i][j] = s[i];
            if(s[i] == ?) 
            {
                for(int l = -1; l <= 1; ++l) if(abs(j + l - 1000) < k && dp[i - 1][j + l])
                {
                    dp[i][j] = dp[i - 1][j + l];
                    if(l == -1) ans[i][j] = W;
                    else if(l == 0) ans[i][j] = D;
                    else if(l == 1) ans[i][j] = L;
                    pre[i][j] = j + l;
                }
            }
            else if(s[i] == W)
            {
                if(abs(j - 1001) < k && dp[i - 1][j - 1]) 
                {
                    dp[i][j] = 1;
                    pre[i][j] = j - 1;
                }
            }
            else if(s[i] == L)
            {
                if(abs(j - 999) < k && dp[i - 1][j + 1]) 
                {
                    dp[i][j] = 1;
                    pre[i][j] = j + 1; 
                }
            }
            else if(s[i] == D)
            {
                if(abs(j - 1000) < k && dp[i - 1][j])
                {
                    pre[i][j] = j;
                    dp[i][j] = 1;
                }
            }
        }
    if(!dp[n][k + 1000] && !dp[n][-k + 1000])
    {
        puts("NO");
        return 0;
    }
    vector<char> v;
    int now = dp[n][k + 1000] ? k + 1000 : -k + 1000;
    for(int i = now, j = n; i && j; i = pre[j][i], --j)
        v.push_back(ans[j][i]);
    reverse(v.begin(), v.end());
    for(int i = 0; i < v.size(); ++i) printf("%c", v[i]);
    return 0;
}
View Code

 

803E