Description
有一只乌龟,初始在000的位置向右跑。
这只乌龟会依次接到一串指令,指令TTT表示向后转,指令FFF表示向前移动一个单位。乌龟不能忽视任何指令。
现在我们要修改其中正好nnn个指令(一个指令可以被改多次,一次修改定义为把某一个TTT变成FFF或把某一个FFF变成TTT)。
求这只乌龟在结束的时候离起点的最远距离。(假设乌龟最后的位置为xxx,我们想要∣x∣|x|∣x∣最大,输出最大的∣x∣|x|∣x∣)
Input
第一行一个字符串ccc表示指令串。ccc只由FFF和TTT构成。
第二行一个整数nnn。
(1≤∣c∣≤100,1≤n≤50)(1\le |c|\le 100, 1\le n\le 50)(1≤∣c∣≤100,1≤n≤50)
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<ndp[i+1][j][k][1−l]=1,ci+1=F,k<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<n\\
dp[i+1][j][k][1-l]=1,c_{i+1}=F,k<n\\
\end{array}
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<ndp[i+1][j][k][1−l]=1,ci+1=F,k<n
最后找到使得dp[m][j][k][l]=1dp[m][j][k][l]=1dp[m][j][k][l]=1且j,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;
}