Newcoder 70 E.乌龟跑步(dp)

本文探讨了一道经典的算法题目,涉及一只乌龟遵循特定指令序列移动的问题。目标是在允许修改一定数量指令的前提下,使乌龟离起点的距离最大化。文章详细解析了动态规划解决方案,并附带实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

有一只乌龟,初始在000的位置向右跑。

这只乌龟会依次接到一串指令,指令TTT表示向后转,指令FFF表示向前移动一个单位。乌龟不能忽视任何指令。

现在我们要修改其中正好nnn个指令(一个指令可以被改多次,一次修改定义为把某一个TTT变成FFF或把某一个FFF变成TTT)。

求这只乌龟在结束的时候离起点的最远距离。(假设乌龟最后的位置为xxx,我们想要∣x∣|x|x最大,输出最大的∣x∣|x|x

Input

第一行一个字符串ccc表示指令串。ccc只由FFFTTT构成。

第二行一个整数nnn

(1≤∣c∣≤100,1≤n≤50)(1\le |c|\le 100, 1\le n\le 50)(1c100,1n50)

Output

一个数字表示答案。

Sample Input

FT
1

Sample Output

2

Solution

dp[i][j][k][l]dp[i][j][k][l]dp[i][j][k][l]表示前iii步走到jjj位置(j∈[−m,m]j\in[-m,m]j[m,m],其中m=∣c∣m=|c|m=c),修改了kkk次且当前方向为正/反方向(l=0/1)(l=0/1)(l=0/1)的这种方案是否存在,若存在,则第i+1i+1i+1步有两种选择,要么不修改要么修改一次,进而有
dp[i+1][j+l?−1:1][k][l]=1,ci+1=Fdp[i+1][j][k][1−l]=1,ci+1=Tdp[i+1][j+l?−1:1][k][l]=1,ci+1=T,k&lt;ndp[i+1][j][k][1−l]=1,ci+1=F,k&lt;n \begin{array}{lcl} dp[i+1][j+l?-1:1][k][l]=1,c_{i+1}=F\\ dp[i+1][j][k][1-l]=1,c_{i+1}=T\\ dp[i+1][j+l?-1:1][k][l]=1,c_{i+1}=T,k&lt;n\\ dp[i+1][j][k][1-l]=1,c_{i+1}=F,k&lt;n\\ \end{array} dp[i+1][j+l?1:1][k][l]=1,ci+1=Fdp[i+1][j][k][1l]=1,ci+1=Tdp[i+1][j+l?1:1][k][l]=1,ci+1=T,k<ndp[i+1][j][k][1l]=1,ci+1=F,k<n
最后找到使得dp[m][j][k][l]=1dp[m][j][k][l]=1dp[m][j][k][l]=1j,nj,nj,n奇偶性相同的∣j∣|j|j最大值即为答案,时间复杂度O(m2n)O(m^2n)O(m2n)

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105;
char s[105];
int n,dp[105][205][55][2];
int main()
{
	scanf("%s%d",s,&n);
	int m=strlen(s);
	dp[0][m][0][0]=1;
	for(int i=0;i<m;i++)
		for(int j=-m;j<=m;j++)
			for(int k=0;k<=n;k++)
				for(int l=0;l<=1;l++)
					if(dp[i][j+m][k][l])
					{
						if(s[i]=='F')dp[i+1][j+(l?-1:1)+m][k][l]=1;
						else dp[i+1][j+m][k][l^1]=1;
						if(k<n)
						{
							if(s[i]=='F')dp[i+1][j+m][k+1][l^1]=1;
							else dp[i+1][j+(l?-1:1)+m][k+1][l]=1;
						}
					}
	int ans=0;
	for(int i=-m;i<=m;i++)
		for(int j=0;j<=n;j++)
			for(int k=0;k<=1;k++)
				if(dp[m][i+m][j][k]&&(n-j)%2==0)
					ans=max(ans,abs(i));
	printf("%d\n",ans);	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值