动态规划之最长不下降子序列
2015-08-31 08:46
447 查看
动态规划的思想就是需要在求得最优解的过程中保存中间结果。在求最长不下降子序列的过程中,我们需要保存每个子序列,然后继续往后判断时将当前元素添加到小于该元素并且最长的子序列当中。譬如有序列2、1、3,首先有一个序列2;然后判断1的时候,前面没有比1小的子序列,因此1独自成为一个序列;最后在判断3的时候,前面的两个子序列2和1都比3小,并且这两个子序列的长度也相等,这个时候两个都满足了,我们暂且就保存一个就ok。因此主要的思想总结如下:
1、对于array(n),从第一个元素开始,首先array(1)自成一个子序列,然后我们从array(2)开始往后寻找。
2、判断array(2)将有两种结果:
- 若array(2) >= array(1), 则存在长度为2的不下降子序列array(1),array(2)以及两个长度为1的不下降子序列。;
- 若array(2) < array(1),则存在两个长度为1的不下降子序列array(1)和array(2)。
3、在判断array(i)时,我们在1~i - 1中找出一个比array(i)且最长的子序列中加入array(i)。
对于每个元素i,我们需要记录的是0~i中包括i的最长子序列maxLen[i],以及元素i所对应的前一个元素preIndex[i]。这里preIndex[i]可能可以取多个值,即当前面有多个长度相同的子序列都小于元素i,我们这里值要求取一个即可,如果题目要求输出所有的最长不下降子序列,则需要保存所有了。
两种要求:
只需要求得最长不下降子序列的长度;这时候就不需要保存前驱了;
需要求出最长不下降子序列;就需要保存preIndex[i]了。
[求最长不下降子序列的长度]
[求最长不下降子序列]
1、对于array(n),从第一个元素开始,首先array(1)自成一个子序列,然后我们从array(2)开始往后寻找。
2、判断array(2)将有两种结果:
- 若array(2) >= array(1), 则存在长度为2的不下降子序列array(1),array(2)以及两个长度为1的不下降子序列。;
- 若array(2) < array(1),则存在两个长度为1的不下降子序列array(1)和array(2)。
3、在判断array(i)时,我们在1~i - 1中找出一个比array(i)且最长的子序列中加入array(i)。
对于每个元素i,我们需要记录的是0~i中包括i的最长子序列maxLen[i],以及元素i所对应的前一个元素preIndex[i]。这里preIndex[i]可能可以取多个值,即当前面有多个长度相同的子序列都小于元素i,我们这里值要求取一个即可,如果题目要求输出所有的最长不下降子序列,则需要保存所有了。
两种要求:
只需要求得最长不下降子序列的长度;这时候就不需要保存前驱了;
需要求出最长不下降子序列;就需要保存preIndex[i]了。
[求最长不下降子序列的长度]
#include <iostream> #include <vector> using namespace std; void main() { int array[10] = {3, 18, 7, 14, 10, 12, 23, 41, 16, 24}; vector<int> nums(array, array + 10); vector<int> maxLen(nums.size()); //记录长度 maxLen[0] = 1; for (int i = 1; i < nums.size(); ++i) { int maxL = 0, maxI = -1; for (int k = i - 1; k >= 0; --k) { if(nums[k] > nums[i]) continue; if(maxLen[k] > maxL) { maxL = maxLen[k]; maxI = k; } } maxLen[i] = maxL + 1; } int maxL = maxLen[0]; for(i = 1; i < nums.size(); ++i) //找出长度最长的不下降子序列,即maxLen[i]最大的情况 { if(maxLen[i] > maxL) maxL = maxLen[i]; } cout<<maxL<<endl; }
[求最长不下降子序列]
#include <iostream> #include <vector> using namespace std; void main() { int array[10] = {3, 18, 7, 14, 10, 12, 23, 41, 16, 24}; vector<int> nums(array, array + 10); vector<int> maxLen(nums.size()); //记录长度 vector<int> preIndex(nums.size()); //记录前一元素下标 maxLen[0] = 1, preIndex[0] = -1; for (int i = 1; i < nums.size(); ++i) { int maxL = 0, maxI = -1; for (int k = i - 1; k >= 0; --k) { if(nums[k] > nums[i]) continue; if(maxLen[k] > maxL) { maxL = maxLen[k]; maxI = k; } } maxLen[i] = maxL + 1; preIndex[i] = maxI; } int maxL = maxLen[0], maxI; for(i = 1; i < nums.size(); ++i) //找出长度最长的不下降子序列,即maxLen[i]最大的情况 { if(maxLen[i] > maxL) { maxL = maxLen[i]; maxI = i; } } do //按照preIndex[]从后往前输出序列 { cout<<nums[maxI]<<" "; maxI = preIndex[maxI]; } while (preIndex[maxI] != -1); cout<<nums[maxI]<<endl; }
相关文章推荐
- 【wechat】微信开发——自定义菜单
- 最高分是多少
- linux下如何退出VI编辑器
- TextView异步加载HTML格式数据中的图片(解决4.0以上主线程加载失败)
- 12v 1a 18w 开关电源原理图
- 如何做实时监控?—— 参考 Spring Boot 实现
- SDUTOJ 3312
- Swift - 集合类型
- 如何做实时监控?—— 参考 Spring Boot 实现
- 如何做实时监控?—— 参考 Spring Boot 实现
- 如何做实时监控?—— 参考 Spring Boot 实现
- SDUTOJ 3312
- 上周热点回顾(8.24-8.30)
- interface builder的身世
- UI 19 数据库的练习
- UVALive - 2197 Paint the Roads(费用流)
- 企业改革的目标
- sql 过了试用期不能启动的,修改时间启动后还原。
- Tabio – 轻松,高效的管理 Chrome 标签页
- POJ 2352 && HDU 1541 Stars(BIT)