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\n",max(dp[len][k][0],dp[len][k][1]));
    return 0;
}
posted @ 2020-05-05 18:58  Valk3  阅读(128)  评论(0编辑  收藏  举报