• 三维递推dp Logo Turtle CodeForces


    https://vjudge.net/problem/CodeForces-132C

    题意:   F表示向前走,T表示向后转,有N次修改字符的机会,问最多能走多远

    思路:dp[ i ][ j ][ d ]表示前i个字符修改了j次,走了k长度,当前朝向是d的状态的最大长度

    所以就可以递推一个关系式,分第i个字符为‘F‘ or ‘T‘时

    然后多维递推dp就是当前 i、j都是由 老i、j递推出来的,即 i-1,j-k,其实就是记忆化暴力。

    注意:要用max就得先全部初始化为-inf,然后dp[0][0][1]、dp[0][0][0] 初始化为0,还要注意 j、k枚举的始末是从0到n、j。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <algorithm>
    using namespace std;
    
    const int maxn=110;
    const int inf = 0x3f3f3f3f;
    char s[maxn];
    int n;
    int dp[110][55][2];   //表示状态 前i位前j个操作后的朝向 (0正1负)
    int main(){ 
        scanf("%s",s+1);
        scanf("%d",&n);
        int len = strlen(s+1);
        for(int i=0; i<=len; i++){
            for(int j=0; j<=n; j++){
                dp[i][j][1] = dp[i][j][0] = -inf;
            }
        }
        dp[0][0][1]=dp[0][0][0]=0;     //初始化以及j、k的循环始末要想仔细
                                        //记忆化暴力
        for(int i=1; i<=len; i++){
            for(int j=0; j<=n; j++){       //前j个操作是从前j-k个操作(前i-1位的)递推来的
                for(int k=0; k<=j; k++){   //选择性分配
                    if(s[i]=='T'){
                        if(k&1){           //多维dp,把i、j用相似的递推思想处理
                            dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][0]+1);
                            dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][1]-1);
                        }   
                        else{
                            dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][1]);
                            dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][0]);
                        }
                    }
                    else{
                        if(k&1){
                            dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][1]);
                            dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][0]);
                        }
                        else{
                            dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][0]+1);
                            dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][1]-1);
                        }
                    }
                }
            }
        }
        printf("%d
    ", max(dp[len][n][0], dp[len][n][1]));
        return 0;
    }
  • 相关阅读:
    安装 oracle
    svn 编辑
    软件构架
    liunx操作
    css的样式分类
    简单自己做了一个个人简历
    网页制作之表格,列表
    MYSQL表创建
    linux操作指令 第二部分
    linux操作指令 第一部分
  • 原文地址:https://www.cnblogs.com/-Zzz-/p/11488418.html
Copyright © 2020-2023  润新知