zoukankan      html  css  js  c++  java
  • CodeForces 803E Roma and Poker

    $dp$。

    $dp[type][i][j]$表示,前i个字符前缀和为$j$,第$i$个字符放的是$type$类型的能否实现,然后倒推回来就可以了。

    #include <cstdio>
    #include <cmath>
    #include <set>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    char s[1010];
    int n,k;
    int dp[3][1010][2010];
    int ans[1010];
    int B = 1000;
    
    void work(int type,int pos,int sum)
    {
        ans[pos] = type;
        if(pos==1) return ;
        
        int E;
        if(type == 0) E=-1; //L
        else if(type == 1) E=1; //W
        else if(type == 2) E=0; //D
    
        for(int i=0;i<3;i++)
        {
            if(dp[i][pos-1][sum-E]==0) continue;
            work(i,pos-1,sum-E);  return ;
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&k);
        scanf("%s",s);
    
        memset(dp,0,sizeof dp);
        dp[0][0][B] = 1;
        dp[1][0][B] = 1;
        dp[2][0][B] = 1;
    
    
        for(int i=1;i<=n;i++)
        {
            if(s[i-1]=='?')
            {
                for(int j=B-k;j<=B+k;j++)
                {
                    if(j+1<=B+k) dp[0][i][j] = max(dp[0][i][j],dp[0][i-1][j+1]);
                    if(j+1<=B+k) dp[0][i][j] = max(dp[0][i][j],dp[1][i-1][j+1]);
                    if(j+1<=B+k) dp[0][i][j] = max(dp[0][i][j],dp[2][i-1][j+1]);
                }
    
                for(int j=B-k;j<=B+k;j++)
                {
                    if(j-1>=B-k) dp[1][i][j] = max(dp[1][i][j],dp[0][i-1][j-1]);
                    if(j-1>=B-k) dp[1][i][j] = max(dp[1][i][j],dp[1][i-1][j-1]);
                    if(j-1>=B-k) dp[1][i][j] = max(dp[1][i][j],dp[2][i-1][j-1]);
                }
    
                for(int j=B-k;j<=B+k;j++)
                {
                    dp[2][i][j] = max(dp[2][i][j],dp[0][i-1][j]);
                    dp[2][i][j] = max(dp[2][i][j],dp[1][i-1][j]);
                    dp[2][i][j] = max(dp[2][i][j],dp[2][i-1][j]);
                }
    
            }
            else if(s[i-1] == 'L')
            {
                for(int j=B-k;j<=B+k;j++)
                {
                    if(j+1<=B+k) dp[0][i][j] = max(dp[0][i][j],dp[0][i-1][j+1]);
                    if(j+1<=B+k) dp[0][i][j] = max(dp[0][i][j],dp[1][i-1][j+1]);
                    if(j+1<=B+k) dp[0][i][j] = max(dp[0][i][j],dp[2][i-1][j+1]);
                }
            }
            else if(s[i-1]=='W')
            {
                for(int j=B-k;j<=B+k;j++)
                {
                    if(j-1>=B-k) dp[1][i][j] = max(dp[1][i][j],dp[0][i-1][j-1]);
                    if(j-1>=B-k) dp[1][i][j] = max(dp[1][i][j],dp[1][i-1][j-1]);
                    if(j-1>=B-k) dp[1][i][j] = max(dp[1][i][j],dp[2][i-1][j-1]);
                }
            }
            else  
            {
                for(int j=B-k;j<=B+k;j++)
                {
                    dp[2][i][j] = max(dp[2][i][j],dp[0][i-1][j]);
                    dp[2][i][j] = max(dp[2][i][j],dp[1][i-1][j]);
                    dp[2][i][j] = max(dp[2][i][j],dp[2][i-1][j]);
                }
            }
            if(i<n)
            {
                dp[0][i][B+k] = 0;
                dp[0][i][B-k] = 0;
                dp[1][i][B+k] = 0;
                dp[1][i][B-k] = 0;
                dp[2][i][B+k] = 0;
                dp[2][i][B-k] = 0;   
            }
        }
    
        int suc=0;
    
        for(int p=0;p<3;p++)
        {
            if(dp[p][n][B+k])
            {
                work(p,n,B+k);
                suc = 1;
                break;
            }
    
            if(dp[p][n][B-k])
            {
                work(p,n,B-k);
                suc = 1;
                break;
            }
        }
    
        if(suc==0)
        {
            printf("NO
    ");
        }
        else 
        {
            for(int i=1;i<=n;i++)
            {
                if(ans[i]==0) printf("L");
                else if(ans[i]==1) printf("W");
                else printf("D");
            }
            printf("
    ");
        }
    
        return 0;
    }
    
  • 相关阅读:
    vs2019编译错误:Exception Processing Message 0xc0000005 Parameters...
    error LNK2001
    Debug Assertion Failed
    对路径“………………”的访问被拒绝
    c语言打开文件为什么总是以二进制方式打开
    关于typedef的用法总结
    xml学习第一天
    关于VS2017编译成功系统找不到指定文件.exe的问题
    引入的外部js文件在html文件在浏览器中乱码显示
    结对作业(四则运算)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6837169.html
Copyright © 2011-2022 走看看