动态规划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/ ...
随机推荐
- Unity 导出设置iOS 项目
别人的代码 xcode打包部分设置的脚本如下 public class XcodeSetting : MonoBehaviour { private static List<Menu> m ...
- find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'
find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'
- oracle数据库常用操作
1,调整显示格式 col username for a20 col DEFAULT_TABLESPACE for a30 2,查看表空间 select username,default_tablesp ...
- 在.NET中使用JWT
1.配置文件添加 //jwt配置文件 "JWT": { "SigningKey": "14fa5f2rrwsg627fs256fdgff2r5rf52 ...
- 使用EFCode First模式
1.添加EntityFrameworkCoreg和EntityFrameworkCore.Design这两个包 2.添加EF上下文类 例如下图如下: 1 using EntityModel; 2 us ...
- 【Golang】Demo
并发控制 package main // demo 参考地址https://studygolang.com/articles/25950 import ( "github.com/siddo ...
- KVM虚拟机根分区磁盘扩容
CentOS7.6, libvirt 4.5.0 , KVM虚拟机根分区扩容. 在宿主机执行0, 对LVM磁盘进行扩容 0. qemu-img resize 10.0.0.1_node1.qcow2 ...
- getopts解析shell脚本命令行参数
getopts命令格式 getopts optstring name [arg] optstring为所有可匹配选项组成的字符串,每个字母代表一个选项.如果字母后有冒号:,表明该选项需要选择参数.比如 ...
- Linux shell字符操作总结
各符号介绍 字符串长度统计 ${#string}: 字符串string的长度 字符串截取 ${string#*substring}: 从左到右截取特定字符substring第一次出现位置之后的字符串 ...
- 计网学习笔记三 MAC与LAN
在上一讲中,我们学习了链路层可以提供的服务:framing,link access,reliable delivery,error detection&correction.这一讲我们从lin ...