题意:点击打开链接
解析:
dp[i][j][k][d]: 能否到达 前i个字符修改j次,并且到达k点方向为d(0,1)的状态
这里要注意1的时候是往右走的k+1,0是往左走的,k-1
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
char str[200];
int dp[110][60][210][2];
int main()
{
int n,m;
scanf("%s",str+1);
scanf("%d",&m);
n=strlen(str+1);
dp[0][0][100][1]=1;
rep(i,1,n)
rep(j,0,m)
rep(k,0,200)
//rep(d,0,1)
{
if(str[i]=='F')
{
//变
if(j) dp[i][j][k][1]|=dp[i-1][j-1][k][0];
if(j) dp[i][j][k][0]|=dp[i-1][j-1][k][1];
//if(j>1&&k) dp[i][j][k][d]|=dp[i-1][j-2][k-1][d];
//if(j>1) dp[i][j][k+1][d]|=dp[i-1][j-2][k][d];
//不变
//dp[i][j][k+1][1]|=dp[i-1][j][k][1];
if(k) dp[i][j][k][1]|=dp[i-1][j][k-1][1];
dp[i][j][k][0]|=dp[i-1][j][k+1][0];
}
else
{
//不变
dp[i][j][k][1]|=dp[i-1][j][k][0];
dp[i][j][k][0]|=dp[i-1][j][k][1];
//变
//if(j) dp[i][j][k+1][d]|=dp[i-1][j-1][k][d];
if(k&&j) dp[i][j][k][1]|=dp[i-1][j-1][k-1][1];
if(j) dp[i][j][k][0]|=dp[i-1][j-1][k+1][0];
//if(j>1) dp[i][j][k][d]|=dp[i-1][j-2][k][d^1];
}
}
int maxx=-1;
rep(i,0,200)
{
if(dp[n][m][i][0]&&abs(i-100)>maxx)
maxx=abs(i-100);
}
rep(i,0,200)
{
if(dp[n][m][i][1]&&abs(i-100)>maxx)
maxx=abs(i-100);
}
printf("%d\n",maxx);
return 0;
}