zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    PeCheck
    模拟木马
    青柠网络验证
    青柠网络验证一键合成工具(exe程序和网络验证合成)
    如果想看我以前发的文章,请到下面地址查看
    星空QQ音乐下载2.0 (可下载收费音乐)
    vmp分析文章
    星空QQ群1.0模块
    青柠网络验证
    Java之IO操作总结
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7640675.html
Copyright © 2011-2022 走看看