• codeforces 132C Logo Turtle(dp)


    可以用三维dp来保存状态, dp[i][j][k]表示在前i个字符变换了j步之后方向为k(k = 1 or k = 0)的最优解,也就是离原点的最大距离。这里规定0方向为正方向,1位负方向,表示的是当前这个人朝哪个方向。这两个方向是对立的。

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

    如果为'F'

      依次枚举在第i个位置变换了几步,这是枚举的范围为0~j, 假设变换了k步(和上面的dp[i][j][k]当中的k不是一个)

        1. 如果当k为奇数的时候,就是相当于变化了1步,所以'F'就变成'T'了,那么他的方向也因此变化了。所以当前的方向一定和上一步(也就是i - 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])

        2.如果k为偶数,相当于没有变化,所以还是字符'F',如果是正方向,那么他就可以由上一步继续向正方向走一步,也就是加1, 如果是负方向,相当于往回走一步,距离就减1,递推方程为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);

    如果为'T'

      依次枚举在第i个位置变化了几步,范围也是0~j,假设变换k步

        1.如果k为奇数,这时就变化成了'F',所以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)

        2.如果k为偶数,这时还是'T',所以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])

    其中还有一个问题就是和刚开始的方向的无关,不用管朝哪个方向,只要走的最远的就行了,而且始终有两个相互对立的方向。初始化的时候dp[0][0][0]和dp[0][0][1]都得初始化0,这样才可以往哪走都可以

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 110;
    int dp[maxn][maxn][2];
    const int inf = 0x3f3f3f3f;
    int main()
    {
        //freopen("in.txt", "r", stdin);
        char cmd[maxn];
        scanf("%s", cmd + 1);
        int n;
        scanf("%d", &n);
        int len = strlen(cmd + 1);
        //memset(dp, -inf, sizeof(dp));
        for (int i = 0; i <= len; i++)
            for (int j = 0; j <= n; j++) dp[i][j][0] = dp[i][j][1] = -inf;
        dp[0][0][0] = 0;//正方向
        dp[0][0][1] = 0;//负方向,两边都可以走
        for (int i = 1; i <= len; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                for (int k = 0; k <= j; k++)
                {
                    if (cmd[i] == 'F')
                    {
                        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);
                        }
                    }
                    else
                    {
    
                        if (k & 1)
                        {
                            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]);
                        }
                    }
                }
    
            }
    
        }
        printf("%d
    ", max(dp[len][n][0], dp[len][n][1]));
        return 0;
    }
    View Code

     

  • 相关阅读:
    670. Maximum Swap
    653. Two Sum IV
    639. Decode Ways II
    636. Exclusive Time of Functions
    621. Task Scheduler
    572. Subtree of Another Tree
    554. Brick Wall
    543. Diameter of Binary Tree
    535. Encode and Decode TinyURL
    博客园自定义背景图片
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/5089983.html
Copyright © 2020-2023  润新知