三维递推dp Logo Turtle CodeForces - 132C
Posted -zzz-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三维递推dp Logo Turtle CodeForces - 132C相关的知识,希望对你有一定的参考价值。
https://vjudge.net/problem/CodeForces-132C
题意: F表示向前走,T表示向后转,有N次修改字符的机会,问最多能走多远
思路:dp[ i ][ j ][ d ]表示前i个字符修改了j次,走了k长度,当前朝向是d的状态的最大长度
所以就可以递推一个关系式,分第i个字符为‘F‘ or ‘T‘时
然后多维递推dp就是当前 i、j都是由 老i、j递推出来的,即 i-1,j-k,其实就是记忆化暴力。
注意:要用max就得先全部初始化为-inf,然后dp[0][0][1]、dp[0][0][0] 初始化为0,还要注意 j、k枚举的始末是从0到n、j。
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <algorithm> using namespace std; const int maxn=110; const int inf = 0x3f3f3f3f; char s[maxn]; int n; int dp[110][55][2]; //表示状态 前i位前j个操作后的朝向 (0正1负) int main() scanf("%s",s+1); scanf("%d",&n); int len = strlen(s+1); for(int i=0; i<=len; i++) for(int j=0; j<=n; j++) dp[i][j][1] = dp[i][j][0] = -inf; dp[0][0][1]=dp[0][0][0]=0; //初始化以及j、k的循环始末要想仔细 //记忆化暴力 for(int i=1; i<=len; i++) for(int j=0; j<=n; j++) //前j个操作是从前j-k个操作(前i-1位的)递推来的 for(int k=0; k<=j; k++) //选择性分配 if(s[i]==‘T‘) if(k&1) //多维dp,把i、j用相似的递推思想处理 dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][0]+1); dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][1]-1); else dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][1]); dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][0]); else if(k&1) dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][1]); dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][0]); else dp[i][j][0] = max(dp[i][j][0], dp[i-1][j-k][0]+1); dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-k][1]-1); printf("%d\n", max(dp[len][n][0], dp[len][n][1])); return 0;
以上是关于三维递推dp Logo Turtle CodeForces - 132C的主要内容,如果未能解决你的问题,请参考以下文章