【题解】乌龟跑步(#3397)

一只乌龟由于智商低下,它只会向左或向右走,不过它会遵循主人小h的指令:F(向前走一步),T(掉头)。

现在小h给出一串指令,由于小h有高超的计算能力,他可以马上知道乌龟最后走到哪里。为了难倒小h,他的好朋友小c就说,现在让你修改其中n个指令,使得乌龟移动到离起点最远的地方。(修改是指“T”变成“F”,或“F”变成“T”,可以对同一个指令多次修改)。乌龟一开始在0点

解析:

其实并不难。

这道题不是做不来,实在是看题不够仔细。。

这里把题目的n用m表示。

首先,本题有两个操作:向前走一步和掉头(掉头是换方向,而不是向后走一步)。本题要我们求m次操作后,使最后乌龟离起点最远。显然,由“恰好m次操作”就可以看出本题绝对不是贪心(约束条件太多),其次,T使前进方向改变,F则是向前走一步,有可能走得远但方向错,而改变方向又会减少操作次数,所以一定想到DP

d p [ i ] [ j ] [ k ] [ l ] dp[i][j][k][l] dp[i][j][k][l]表示第i个操作序列,用了j次改变操作,k=1表示正向,k=0表示反向,l=0表示离起点最大,l=1表示离起点最小(反方向的最远)。显然满足最优子结构,离起点越大或越小最好,因为离起点的距离不影响决策。

a [ i ] = = T a[i]==T a[i]==T时:

  1. 改变为F,方向不变,走一格,到下一个操作序列
  2. 不变,方向变反,不动,到下一个操作序列

a [ i ] = = F a[i]==F a[i]==F时:

  1. 改变为T,方向变反,不动,到下一个操作序列
  2. 不变,方向不变,走一格,到下一个操作序列

注意:可以使用两次改变操作,变为j+2,其他参数不变

边界: d p [ n + 1 ] [ m ] [ k ] [ l ] = 0 dp[n+1][m][k][l]=0 dp[n+1][m][k][l]=0
d p [ i ] [ j ] [ k ] [ l ] = + − 0 x 3 f 3 f 3 f 3 f ( j > m ) dp[i][j][k][l]=+-0x3f3f3f3f (j>m) dp[i][j][k][l]=+0x3f3f3f3f(j>m)

#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
char a[maxn];
int n,m,dp[maxn][maxn][2][2];
bool g[maxn][maxn][2][2];
int dfs(int i,int j,int k,int l) {
    
    //0是max,1是min 
	if(i>n) {
    
    
		if(j==m) return 0;
		else return ((l==1)?0x3f3f3f3f:-0x3f3f3f3f);
	}
	if(j>m) return ((l==1)?0x3f3f3f3f:-0x3f3f3f3f);
	if(g[i][j][k][l]) return dp[i][j][k][l];
	g[i][j][k][l]=1;
	if(a[i]=='F') {
    
    
		dp[i][j][k][l]=dfs(i+1,j,k,l)+((k==1)?1:-1);
		if(l==0) {
    
    
			dp[i][j][k][l]=max(dp[i][j][k][l],dfs(i+1,j+1,1-k,l));
		}
		else {
    
    
			dp[i][j][k][l]=min(dp[i][j][k][l],dfs(i+1,j+1,1-k,l));
		}
	}
	else if(a[i]=='T') {
    
    
		dp[i][j][k][l]=dfs(i+1,j,1-k,l);
		if(l==0) {
    
    
			dp[i][j][k][l]=max(dp[i][j][k][l],dfs(i+1,j+1,k,l)+((k==1)?1:-1));
		}
		else {
    
    
			dp[i][j][k][l]=min(dp[i][j][k][l],dfs(i+1,j+1,k,l)+((k==1)?1:-1));
		}
	}
	if(l==0) {
    
    
		dp[i][j][k][l]=max(dp[i][j][k][l],dfs(i,j+2,k,l));
	}
	else {
    
    
		dp[i][j][k][l]=min(dp[i][j][k][l],dfs(i,j+2,k,l));
	}
	return dp[i][j][k][l];
}
int main() {
    
    
	memset(dp,-1,sizeof(dp));
	scanf("%s%d",a+1,&m);
	n=strlen(a+1);
	printf("%d",max(abs(dfs(1,0,1,0)),abs(dfs(1,0,1,1))));
}

猜你喜欢

转载自blog.csdn.net/cqbzlydd/article/details/107646039