动态规划DP入门问题----最大连续子序列,最长不下降子序列(可以不连续),最长公共子序列
一、最大连续子序列
1.题目叙述
对于一个数字序列A1A2A3...An,求出连续子序列的最大和,如对于序列-2,11,-4,13,-5,-2,其中的最大序列和是11+(-4)+13=20
2.动态规划解法
将问题拆分成子问题,即dp[i]表示以A[i]为结尾的子序列的最大和,最后对于这些dp数组找出最大值即可,状态转移方程为:
dp[i] = max{ dp[i-1] + A[i] } 状态dp[i]表示,当前以A【i】结尾的子序列的最大和3.方法一是经典算法,方法二是根据状态方程优化而来。
#include<iostream>
#include<algorithm>
using namespace std;
int maxSum1(int arr[],int n){
int dp[10];
int ans = INT32_MIN;
dp[0] = arr[0];//初始化
for(int i=1;i<n;i++){
dp[i] = max(dp[i-1]+arr[i], arr[i]);
ans = max(ans,dp[i]);
}
return ans;
}
int maxSum2(int arr[],int n){
int dp = arr[0];
int m = arr[0];
for(int i=1;i<n;i++){
if(dp<0){
dp = arr[i];
}
else dp+=arr[i];
if(dp>m){
m = dp;
}
}
return m;
}
int main(){
//-2,6,-1,5,4,-7,2,3
//dp[i] = max{dp[i-1]+A[i], A[i]}
int arr[8]={-2,6,-1,5,4,-7,2,3};
cout<<"algorithm 1:" <<maxSum1(arr,8)<<endl;
cout<<"algorithm 2: "<<maxSum2(arr,8)<<endl;
return 0;
}
二、最长公共子序列(可以不连续)
状态转移函数:
if(a == b)
dp[i][j] = dp[i-1][j-1] + 1;
else{
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
for(int i=1; i<=n1; i++){
for(int j=1; j<=n2; j++){
char a = text1[i-1];
char b = text2[j-1];
if(a == b)
dp[i][j] = dp[i-1][j-1] + 1;
else{
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
}
观察可以发现空间可以使用两个一维数组即可
for(int i=1; i<=n1; i++){
for(int j=1; j<=n2; j++){
char a = text1[i-1];
char b = text2[j-1];
if(a == b)
dp[i%2][j] = dp[(i+1)%2][j-1] + 1;
else{
dp[i%2][j] = max(dp[(i+1) % 2][j], dp[i][j-1]);
}
}
}
三、最长单调递增序列
状态转移方程:
dp[i]=max(dp[j])+1,其中0≤j<i且num[j]<num[i]
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> dp(nums.size());
dp[0] = 1;
int ans = 1;
for(int i=1; i<nums.size(); i++){
int cur_max = 0;
for(int j=0; j<i; j++){
if(nums[j] < nums[i])
cur_max = max(cur_max, dp[j]);
}
dp[i] = cur_max + 1;
cout<<dp[i]<<" ";
ans = max(ans, dp[i]);
}
return ans;
}
};
时间复杂度\(O(n^2)\)
也可以使用贪心加二分的方法,基本思路举个例子就比较容易明白,比如序列是78912345,前三个遍历完以后tail是789,这时候遍历到1,就得把1放到合适的位置(使用二分),于是在tail二分查找1的位置,变成了189(如果序列在此时结束,因为res不变,所以依旧输出3),再遍历到2成为129,然后是123直到12345 .
动态规划DP入门问题----最大连续子序列,最长不下降子序列(可以不连续),最长公共子序列的更多相关文章
- 《 动态规划_ 入门_最大连续子序列_HDU_1003 》
题目描述: Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 动态规划DP入门
百度百科↓ 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.20世纪50年代初美国数学家R.E.Bellman ...
- 算法导论-动态规划(最长公共子序列问题LCS)-C++实现
首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2 ...
- 【线型DP模板】最上上升子序列(LIS),最长公共子序列(LCS),最长公共上升子序列(LCIS)
BEGIN LIS: 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序 ...
- 最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)
最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...
- 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr
问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk ...
- 动态规划法(十)最长公共子序列(LCS)问题
问题介绍 给定一个序列\(X=<x_1,x_2,....,x_m>\),另一个序列\(Z=<z_1,z_2,....,z_k>\)满足如下条件时称为X的子序列:存在一个严格 ...
- 算法实践--最长公共子序列(Longest Common Subsquence)
什么是最长公共子序列 X=ACCG Y=CCAGCA 长度为1的公共子序列: {A} {C} {G} 长度为2的公共子序列:{AC} {CC} {CG} {AG} 长度为3的公共子序列:{ACG} 长 ...
- noj最长公共子序列
1041.最长公共子序列 时限:1000ms 内存限制:200000K 总时限:3000ms 描述 一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列X=<x1, ...
- dp经典问题-最大连续子序列和 hdu1003
题目描述: 这道题我先后做过三遍,结果每一遍都没有做出来.今天再仔仔细细的研究了一下,才发现用动态规划更好理解. 关于求最大连续子序列和的博文转载如下:https://www.cnblogs.com/ ...
随机推荐
- [Leetcode 108]有序数组转BST二叉搜索树Convert Sorted Array to Binary Search Tree
题目 https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ Given an integer array ...
- 如何确保获取的输入为整数-C语言基础
这一篇探讨的是如何确保你输入的数据是一个整数.虽然标题用的是这个,但我其实真正想要探讨的内容是 "在程序调试的过程中,需要注意把输入缓存区中的上一次输入的残留信息清理干净,以免影响下一次的输 ...
- getopt函数使用说明
一.查询linux命令手册: #include<unistd.h> #include<getopt.h> /*所在头文件 */ int getopt(intargc, char ...
- rules验证数值大于0
[['mobile'],'number'],[['mobile'],'compare','compareValue' =>0,'operator' => '>']compare对比, ...
- postgres 表字段修改
更换字段名 alter table 表名 rename column 字段名 to 新字段名; 更换表名 alter table 表名 rename to 新表名; 更改字段长度 alter tabl ...
- Go_day04
Go基础语法 指针 指针式存储另一个变量内存地址的变量 &a 取出a的内存地址 *b 若指针b存放的式a的地址 那么 *b就直接指向a的内存 可以直接操作其中的值 指针的使用 func mai ...
- python requests 上传文件_python3使用requests上传文件,content-type踩的坑
通常提交普通表单时,requests的post方法可以指定headers,所以我在使用requests模拟上传文件行为时,直接按照下面的方式写了: 然后服务器就报出了找不到分隔符Invalid mul ...
- SQLServer游标(Cursor)简单例子
DECLARE @username nvarchar(50),@password nvarchar(50),@num int--声明游标变量 DECLARE myCursor CURSOR FOR s ...
- vue中的观察者模式和发布订阅者模式
观察者模式 目标者对象和观察者对象有相互依赖的关系,观察者对某个对象的状态进行观察,如果对象的状态发生改变,就会通知所有依赖这个对象的观察者, 目标者对象 Subject,拥有方法:添加 / 删除 / ...
- Node.js server使用
一.创建项目 #创建项目目录 cd /data mkdir webroot cd webroot #初始化git git init vim .gitignore 输入: node_modules/ 保 ...