三维递推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;
}

原文地址:https://www.cnblogs.com/-Zzz-/p/11488418.html

时间: 2025-01-16 11:47:58

三维递推dp Logo Turtle CodeForces - 132C的相关文章

CodeForces Round#229 DIV2 C 递推DP

对这道题目也只好说呵呵了,没注意k的范围最大才10,所以昨晚纠结了很久,没什么好的方法来处理,后来无奈想去翻翻题解,发现人家开头就来了句,因为k的范围比较小 所以.........我只好暂停马上回头看看题目,是的,k比较小所以完全可以先在询问前预处理DP一遍, DP就比较清晰了,dp[i][j]  (i>=0 && i<k,,,,j>=i && j <=n)代表意义呢 以i为开头的  区间[1,j]注意 是 1~j的 所需要的操作数,题目问的是最小操

D. Caesar&#39;s Legions 背包Dp 递推DP

http://codeforces.com/problemset/problem/118/D 设dp[i][j][k1][k2] 表示,放了i个1,放了j个2,而且1的连续个数是k1,2的连续个数是k2 如果这样写,用dfs写是很简单的.但是超时,我记忆化不到 如果用递推写,对于每一个状态,更新到下一个状态. 如果放的是1,那么新的状态是dp[i + 1][j][k1 + 1][0]也就是,用多了一个1,而且连续的个数也增加了.同时,2的连续个数就打破了,变成了0 这种枚举旧状态,更新下一个状态

hdu 1284 钱币兑换问题 (递推 || DP || 母函数)

钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5069    Accepted Submission(s): 2868 Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Outpu

递推DP URAL 1031 Railway Tickets

题目传送门 1 /* 2 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 3 注意:s1与s2大小不一定,坑! 4 详细解释:http://blog.csdn.net/kk303/article/details/6847948 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <s

递推DP URAL 1119 Metro

题目传送门 1 /* 2 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 3 递推DP:仿照JayYe,处理的很巧妙,学习:) 4 好像还要滚动数组,不会,以后再补 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 #include <cs

Code Force 429B Working out【递推dp】

Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and mcolumns. Let number a[i][j] represents the calories burned by performing workout at the

递推DP UVA 607 Scheduling Lectures

题目传送门 题意:教授给学生上课,有n个主题,每个主题有ti时间,上课有两个限制:1. 每个主题只能在一节课内讲完,不能分开在多节课:2. 必须按主题顺序讲,不能打乱.一节课L时间,如果提前下课了,按照时间多少,学生会有不满意度.问最少要几节课讲完主题,如果多种方案输出不满意度最小的 分析:dp[i]表示前i个主题最少要多少节课讲完,那么这个主题可能和上个主题在同一节课讲或者多开新的一节课讲,状态转移方程:看代码:优先满足节数少的情况 收获:普通的递推DP 代码: /**************

[递推dp] zoj 3747 Attack on Titans

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5170 Attack on Titans Time Limit: 2 Seconds      Memory Limit: 65536 KB Over centuries ago, mankind faced a new enemy, the Titans. The difference of power between mankind and their newf

递推DP URAL 1353 Milliard Vasya&#39;s Function

题目传送门 1 /* 2 题意:1~1e9的数字里,各个位数数字相加和为s的个数 3 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 4 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 5 改为:dp[i][j+k] += dp[i-1][j] 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm