CodeForces 803E Roma and Poker dp递推

CodeForces 803E

题意:给出长度为n的字符串和一个数 k ,字符串有 'W' 表示 +1, 'L' 表示 -1, 'D' 表示 0 , '?' 表示不确定。现在要你确定 '?', 问有没有一种方案使得最后所有字符的和等于 k 或者 -k ,且任意长度小于 k 的前缀和不能等于 k 和 -k 。

tags:因为 n <=1000 ,故前缀和的范围是在 -1000至1000 ,所以考虑 dp 。

dp[i][j] 表示前 i 个字符的前缀和为 j 是否可能,同时记录第 i 个字符是什么,最后倒推回去即可。

因为 j 会是负数,我们可以加上一个数比较大的数使之为正数。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 1005, M = 2*N;

int n, k, dp[N][M];
char s[N];
int main()
{
    scanf("%d%d%s", &n, &k, s+1);
    dp[0][1005]=-2;
    rep(i,1,n-1)
    {
        if(s[i]!='?')
        {
            int tmp = (s[i]=='W' ? 1 : (s[i]=='L' ? -1 : 0));
            rep(j, N-k+1, N+k-1 ) if(dp[i-1][j-tmp])
            {
                dp[i][j] = (tmp ? tmp : 2);
            }
        }
        else
        {
            rep(tmp, -1, 1)
            {
                rep(j, N-k+1, N+k-1 ) if(dp[i-1][j-tmp])
                {
                    dp[i][j] = (tmp ? tmp : 2);
                }
            }
        }
    }

        if(s[n]!='?')
        {
            int tmp = (s[n]=='W' ? 1 : (s[n]=='L' ? -1 : 0));
            rep(j, N-k, N+k ) if(dp[n-1][j-tmp])
            {
                dp[n][j] = (tmp ? tmp : 2);
            }
        }
        else
        {
            rep(tmp, -1, 1)
            {
                rep(j, N-k, N+k ) if(dp[n-1][j-tmp])
                {
                    dp[n][j] = (tmp ? tmp : 2);
                }
            }
        }

        int cnt=0, j2[3]={N-k, N+k};
        rep(j, 0,1) if(dp[n][j2[j]])
        {
            int jj=j2[j];
            per(i,n,1)
            {
                s[++cnt] = (dp[i][jj]==1 ? 'W' : (dp[i][jj]==-1 ? 'L' : 'D'));
                jj = (dp[i][jj]==1 ? jj-1 : (dp[i][jj]==-1 ? jj+1 : jj));
            }
            per(i,cnt,1) putchar(s[i]);
            return 0;
        }
    puts("NO");

    return 0;
}
原文地址:https://www.cnblogs.com/sbfhy/p/7640675.html