最长有序子序列—动态规划算法

动态规划使用范围:(http://baike.baidu.com/view/28146.htm)

任何思想方法都有一定的局限性,超出了特定条件,它就失去了作用。同样,动态规划也并不是万能的。适用动态规划的问题必须满足最优化原理和无后效性。   

1.最优化原理(最优子结构性质) 最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质。   

2.无后效性 将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。   

3.子问题的重叠性 动态规划将原来具有指数级复杂度的搜索算法改进成了具有多项式时间的算法。其中的关键在于解决冗余,这是动态规划算法的根本目的。 动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其它的算法。

动态规划思想:

       如果各个子问题不是独立的,不同的子问题的个数只是多项式量级,如果我们能够保存已经解决的子问题的答案,而在需要的时候再找出已求得的答案,这样就可以避免大量的重复计算。由此而来的基本思路是,用一个表记录所有已解决的子问题的答案,不管该问题以后是否被用到,只要它被计算过,就将其结果填入表中。

时间复杂度为O(n^2),算法原理:

数组a[]为待处理数组

f[]用于记录a[]数组中,以对应位置数据为结尾的最长有序序列长度

p[]用于记录a[]数组中,以对应位置数据为结尾的前一个数据位置

使用position记录最大长度位置

以a[]={1,4,7,2,5,8,3,6,9},计算最长递增有序子序列为例

初始化f[]={1, 1, 1, 1, 1, 1, 1,1,1},p[]={0,1,2,3,4,5,6,7,8}

计算f[i]时,f[i]=max(f[j]+1) ,(其中,a[i]>a[j],i>j>=0),意思是以a[i]为结尾,找出在a[i]前比a[i]小的数据中以该数据为结尾的最大有序子序列长度max(f[j]),则以a[i]结尾的最大有序子序列长度为max(f[j])+1。计算同时定义p[i]=j,标志a[i]为结尾的最长子序列的前一个数据a[j]的位置。同时判断此时最大长度a[i]是否比当前最大长度max大,如果a[i]更大则更新position

a[]={1,4,7,2,5,8,3,6,9}

i=0   f[]={1,1,1,1,1,1,1,1,1},  p[]={0,1,2,3,4,5,6,7,8}

i=1   f[]={1,2,1,1,1,1,1,1,1},  p[]={0,0,2,3,4,5,6,7,8}  4>1,所以最大长度为2,position=1

i=2   f[]={1,2,3,1,1,1,1,1,1},  p[]={0,0,1,3,4,5,6,7,8}  7>4,7>1 其中4结尾的长度为2,所以最大长度为3,position=2

i=3   f[]={1,2,3,2,1,1,1,1,1},  p[]={0,0,1,0,4,5,6,7,8}  2>1 所以最大长度为2

i=4   f[]={1,2,3,2,3,1,1,1,1},  p[]={0,0,1,0,1,5,6,7,8}  5>1,5>4,5>2,其中以4结尾的长度为2,所以最大长度为3

i=5   f[]={1,2,3,2,3,4,1,1,1},  p[]={0,0,1,0,1,2,6,7,8}  8比前面的数据都大,所以最大长度为4,position=5

i=6   f[]={1,2,3,2,3,4,3,1,1},  p[]={0,0,1,0,1,2,3,7,8}  3>1,3>2,其中以2结尾的长度为2,所以最大长度为3

i=7   f[]={1,2,3,2,3,4,3,4,1},  p[]={0,0,1,0,1,2,3,4,8}  6>1,6>4,6>2,6>5,6>3,其中以5结尾长度为3,所以最大长度为4

i=8   f[]={1,2,3,2,3,4,3,4,5},  p[]={0,0,1,0,1,2,3,4,5}  9比前面数据都大,所以最大长度为5,position=8

在对所有a中元素循环过后,通过max记录下最后数据位置,以及p记录的前一个数据的位置,可以递归求出LIS

代码如下:

[cpp] view plaincopy
  1. #include<stdio.h>  
  2.   
  3. int a[10000]={0};  
  4. int f[10000]={0};  
  5. int p[10000]={0};  
  6. int max=0;  
  7. int position =0;  
  8. void compare(int n){  
  9.     for(int i=0; i<n; i++){  
  10.         for(int j=0; j<i; j++){  
  11.             if(a[i]>a[j]){  
  12.                 if(f[i]<f[j]+1){  
  13.                     f[i]=f[j]+1;  
  14.                     p[i]=j;  
  15.                     if(f[i]>max){  
  16.                         postiion=i;  
  17.                         max = f[i];  
  18.                     }  
  19.                 }  
  20.             }  
  21.         }  
  22.     }  
  23. }  
  24.   
  25. void printLIS(int position){          
  26.     if(p[position]==position){  
  27.         printf("%d",a[position]);  
  28.         return;  
  29.     }  
  30.     printLIS(p[position]);  
  31.     printf(" %d",a[position]);  
  32. }  
  33.   
  34. void main(){  
  35.     int n;  
  36.     max =0;  
  37.     position = 0;  
  38.     scanf("%d",&n);  
  39.     for(int i=0; i<n; i++){  
  40.         scanf("%d",&a[i]);  
  41.         f[i]=1;  
  42.         p[i]=i;  
  43.     }  
  44.     compare(n);  
  45.     printLIS(position);  
  46.     printf("\n");  
  47. }  

 又如hdoj中的 1160 FatMouse's Speed

Problem Description
FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speeds are decreasing.


 

Input
Input contains data for a bunch of mice, one mouse per line, terminated by end of file.

The data for a particular mouse will consist of a pair of integers: the first representing its size in grams and the second representing its speed in centimeters per second. Both integers are between 1 and 10000. The data in each test case will contain information for at most 1000 mice.

Two mice may have the same weight, the same speed, or even the same weight and speed.


 

Output
Your program should output a sequence of lines of data; the first line should contain a number n; the remaining n lines should each contain a single positive integer (each one representing a mouse). If these n integers are m[1], m[2],..., m[n] then it must be the case that

W[m[1]] < W[m[2]] < ... < W[m[n]]

and

S[m[1]] > S[m[2]] > ... > S[m[n]]

In order for the answer to be correct, n should be as large as possible.
All inequalities are strict: weights must be strictly increasing, and speeds must be strictly decreasing. There may be many correct outputs for a given input, your program only needs to find one.


 

Sample Input
6008 1300 6000 2100 500 2000 1000 4000 1100 3000 6000 2000 8000 1400 6000 1200 2000 1900


 

Sample Output
4 4 5 9 7

 

代码如下:

[cpp] view plaincopy
  1. #include<stdio.h>  
  2. #include<algorithm>  
  3. using namespace std;  
  4.   
  5. int f[10001];  
  6. int p[10001];  
  7.   
  8. struct Mouse{  
  9.     int w;  
  10.     int s;  
  11.     int n;  
  12. }Mic[10001];  
  13.   
  14. bool compare(const Mouse &a, const Mouse &b){  
  15.     if(a.w==b.w)  
  16.         return a.s > b.s;  
  17.     else  
  18.         return a.w < b.w;  
  19. }  
  20.   
  21. void printLIS(int max_l){         
  22.     if(p[max_l]==max_l){    
  23.         printf("%d\n",Mic[max_l].n);    
  24.         return;    
  25.     }    
  26.     printLIS(p[max_l]);    
  27.     printf("%d\n",Mic[max_l].n);    
  28. }   
  29.   
  30. void main(){  
  31.     int i=1,max=0,max_l=0;  
  32.     while(scanf("%d %d",&Mic[i].w,&Mic[i].s)!=EOF){  
  33.         f[i]=1;  
  34.         p[i]=i;  
  35.         Mic[i].n=i;  
  36.         i++;  
  37.     }  
  38.     sort(Mic+1,Mic+i,compare);  
  39.   
  40.     for(int k=1; k<i+1; k++){  
  41.         for(int j=1; j<k; j++){  
  42.             if(Mic[j].s>Mic[k].s&&Mic[j].w<Mic[k].w){  
  43.                 if((f[j]+1)>f[k]){  
  44.                     f[k]=f[j]+1;  
  45.                     p[k]=j;  
  46.                     if(f[k]>max){  
  47.                         max = f[k];  
  48.                         max_l = k;  
  49.                     }  
  50.                 }  
  51.             }  
  52.         }  
  53.     }  
  54.     printf("%d\n",max);  
  55.     printLIS(max_l);  
  56. }  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces 666E. Forensic Examination

Description 给出串 \(S\) ,和 \(m\) 个串 \(T_i\) ,每次询问 \((l,r,pl,pr)\) 表示 \(S[pl...pr]\) 在 \(T[l...r]\) 中哪一个出现次数最多,求出现次数和编号题面 Solution 基础题... 对于 \(S,T[l...r]\) 放在一起建广义后缀自动机 然后每次倍增到 S[pl,pr] ,然后查询子树内出…

Matlab控制精度

控制精度matlab控制运算精度用的是digits和vpa这两个函数digits用于规定运算精度&#xff0c;比如&#xff1a;digits(20);这个语句就规定了运算精度是20位有效数字。但并不是规定了就可以使用&#xff0c;因为实际编程中&#xff0c;我们可能有些运算需要控制精度&#xff0c;…

虚拟机环境下DPDK运行时的一些错误解决

在绑定网卡到DPDK模块时 报错 &#xff1a;is active. Not modifyingRouting table indicates that interface 0000:02:01.0 is active. Not modifying 解决方法&#xff1a; ifconfig <网卡名称> down 运行testpmd时无法分配内存&#xff1a;EAL: Error - exiting with …

ACM 网址和一些建议

USACO http://ace.delos.com/usacogate 美国著名在线题库&#xff0c;专门为信息学竞赛选手准备 TJU http://acm.tongji.edu.cn/ 同济大学在线题库&#xff0c;唯一的中文题库&#xff0c;适合NOIP选手 ZJU http://acm.zju.edu.cn/ 浙江大学在线题库 JLU http://acm.jlu…

使用Boxfuse轻松在云中运行Spring Boot应用程序

几天前&#xff0c;我开始构建一个将使用REST API检索和存储数据的iOS应用。 该REST API将是我也必须构建的服务器应用程序。 由于我熟悉Java和Spring &#xff0c;因此决定使用Spring Boot作为框架。 为了能够在我的iPhone上使用它&#xff0c;如果我可以在服务器而不是我自己…

Matlab各种求和

%普通求和sum(x);sum(x,1);sum(x,2); %累加求和cumsum(x);cumsum(x,1);cumsun(x,2); %累加求和的结果可以用diff实现逆运算

JavaScript内置对象Date----格式化时间

格式化时间日期: function getDate(dt) { //获取年份 var year dt.getFullYear(); //获取月份 var month dt.getMonth(); //获取日 var day dt.getDate(); //获取小时 var hour dt.getHours(); //获取分钟 var minute dt.getMinutes(); …

Matlab求欧式距离

pdist(x,‘euclidean’)1. %该函数还可以求其他距离&#xff0c;详见help2. %该函数得到的是一个向量&#xff0c;可以用squareform(Y)函数转换为对称矩阵形式。

川流不息

网站收藏&#xff1a; 1、站长网 网页教程与代码 2、博客制作 3、Java实例编程 贪吃蛇游戏开发视频教程

dao层通用封装_DAO层–救援通用

dao层通用封装泛型可以是使用编译时验证&#xff08;类型安全性&#xff09;的功能来创建可重用代码的强大工具。 不幸的是&#xff0c;我感到主流开发人员仍然对此感到恐惧。 但是&#xff0c;比喻海格的蜘蛛&#xff0c;我会说&#xff0c;泛型是被严重误解的生物……:-) 我…

(转) Linux 内核运行参数修改——sysctl命令

原文&#xff1a;https://blog.csdn.net/u012707739/article/details/78254241 sysctl命令被用于在内核运行时动态地修改内核的运行参数&#xff0c;可用的内核参数在目录/proc/sys中。它包含一些TCP/ip堆栈和虚拟内存系统的高级选项&#xff0c;用sysctl可以读取设置超过五百个…

Matlab求平均值函数mean

amean(A,1) %按列平均bmean(A,2) %按行平均cmean(A(:)) %全部平均

HDU 4514 湫湫系列故事——设计风景线

一次dfs判断有没有环 两次dfs求最长路 第一次记录最长路和次长路 第二次求出答案 #include <iostream>#include <string>#include <cstring>#include <algorithm>#include <cstdio>#define maxn 100010#pragma comment(linker, "/STACK:367…

numpy的使用数组的创建2

随机创建了长度为十的数组 获得十以类的随机整数 快速获取数组2乘3维的数组 生成20个1到10之间的数组 通过reshape 将这些数变成二位数组 shape这个方法可以查看数组中的元素是几行几列的 转载于:https://www.cnblogs.com/chenligeng/p/9315339.html

Tabs vs Spaces:如何在Google,Twitter,Mozilla和Pied Piper上编写Java

流行的Java代码样式中最有趣的亮点是什么&#xff1f; 尽管上面有暗示性的形象&#xff0c;我们也不想发动任何不必要的圣战。 当归结为编码样式时&#xff0c;大多数选择都是相当随意的&#xff0c;并取决于个人喜好。 是的&#xff0c;即使在编辑器之间制表符宽度改变了&…

Matlab数据标准化

zscore%据说就是原数据减去均值再除以标准差标准回归系数&#xff1a;1、标准化回归系数测度的是对被解释变量的重要性&#xff0c;只有标准化了&#xff0c;才能进行重要性对比。

matlab学习-线性规划

[x,fval,exitflag,output,lambda]linprog(f,a,b,aeq,beq,lb,ub) 其中f、x、b、beq、lb、ub为向量&#xff0c;a、aeq为矩阵。 min zf s.t. a*x<b aeq*xbeq lb<x<ub x:线性规划最优解 fval&#xff1a;线性规划最优值 exitflag&#xff1a;输出标…

bug单的提交

顶头信息 所属产品&#xff0c;所属项目&#xff0c;所属模块&#xff0c;影响版本&#xff0c;当前指派&#xff0c;bug类型&#xff1a;代码错误&#xff0c;界面优化&#xff0c;设计缺陷&#xff0c;性能问题&#xff0c;标准规范&#xff0c;其他&#xff0c;安全相关。bu…

Matlab各种随机数汇总

randn();%正态分布随机数R&#xff1d;normrnd(MU,SIGMA)R&#xff1d;normrnd(MU,SIGMA,m)R&#xff1d;normrnd(MU,SIGMA,m,n) 注&#xff1a;正态分布只需要2个参数。 randn() 是标准正态分布&#xff1b;normrnd()是自己可以指定均数和标准差的正太分布。rand();randi();是…

ES group分组聚合的坑

参考链接&#xff1a;https://blog.csdn.net/u010454030/article/details/71762838 ES group分组聚合的坑 原来知道Elasticsearch在分组聚合时有一些坑但没有细究&#xff0c;今天又看了遍顺便做个笔记和大家分享一下。 我们都知道Elasticsearch是一个分布式的搜索引擎&#xf…