zoukankan      html  css  js  c++  java
  • CF#132 C. Logo Turtle DP

    C. Logo Turtle

    题意

    有一个海龟在一个x轴的0点,给出一个由'F','T'组成的字符序列。

    海龟要按照这个序列进行行动,如果第i个字符为'F',表示沿当前方向走,'T'表示转身。

    现在你必须改变n个操作,把'F'变成'T',或者把'T'变成'F',同一个操作可以改变多次,问终点距离起点最大距离。

    思路

    看数据范围就是DP。

    先说正解。

    dp[i][j][0]表示执行完前i步,改变了j次,方向为正对起点的最大距离

    dp[i][j][1]表示执行完前i步,改变了j次,方向为背对起点的最大距离

    对于每个操作,枚举改变的次数num,然后分别讨论为F,T的情况

    str[i]=='F':

    1. num%2==0 :改变偶数次相当于没改变,向前走了一步

      dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-num][0]-1);正对起点向前走,距离减小1

      dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-num][0]+1);与上相反

    2. num%2==1:改变奇数次相当于改变一次,转身

      dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-num][1]);

      dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-num][0]);

    str[i]=='T': 就和F中num的奇偶性相反

    初始化dp[0][0][0]=dp[0][0][1]=0.,其他为负无穷

    这题我想了两个DP方程,上面是第二个。

    第一个是dp[i][j][k][l]表示前i个命令距离起点为j改变了k次朝向为l是否可行

    GG了,写了好久混乱了

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int N=1e4+10;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    
    int dp[110][110][55];
    /*
    dp[i][j][k]前i条命令改变了j次,朝向为k的最远距离
    */
    char str[N];
    int main()
    {
        scanf("%s",str+1);
        int len=strlen(str+1),k;
        scanf("%d",&k);
        memset(dp,0x8f,sizeof(dp));
        dp[0][0][1]=0;
        dp[0][0][0]=0;
        for(int i=1; i<=len; i++)
        {
            for(int j=0; j<=k; j++)
            {
                for(int l=0; l<=j; l++)
                {
                    if(str[i]=='F')
                    {
                        if(l%2)
                        {
                            dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-l][1]);
                            dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-l][0]);
                        }
                        else
                        {
                            dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-l][1]+1);
                            dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-l][0]-1);
                        }
    
                    }
                    else
                    {
                        if(l%2==0)
                        {
                            dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-l][1]);
                            dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-l][0]);
                        }
                        else
                        {
                            dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-l][1]+1);
                            dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-l][0]-1);
                        }
                    }
                }
            }
        }
        printf("%d
    ",max(dp[len][k][0],dp[len][k][1]));
        return 0;
    }
    
  • 相关阅读:
    C++之路进阶——codevs2439(降雨量)
    C++之路进阶——codevs2933(诗人小G)
    C++之路进阶——bzoj2879(美食节)
    C++之路进阶——bzoj1934(善意的投票)
    C++之路进阶——bzoj3876(支线剧情)
    C++之路进阶——codevs1281(Xn数列)
    八数码难题
    道路游戏
    细胞分裂
    最长链
  • 原文地址:https://www.cnblogs.com/valk3/p/12831966.html
Copyright © 2011-2022 走看看