首页 > 编程知识 正文

简述动态规划的基本思想,动态规划算法的适用条件

时间:2023-05-06 17:32:25 阅读:150165 作者:1431

介绍

动态规划(简称DP )是算法设计思想中最难最无私的钻石部分。 动态规划适用于重叠子问题和具有最优子结构性质的问题,在数学、计算机科学、经济学中很常用,是将原问题分解为比较简单的子问题来求解复杂问题的方法。 使用动态规划方法求解问题,时间效率较高。 重要的是大幅减少不必要的计算和重复计算的部分

其思想是将大问题进行分割,细分为小问题,再由该小问题的解导出原问题的解。 要进行动态规划,必须满足以下两个重要性质

最优子结构性:是分割后的子问题的解是最优解。

子问题的重叠性质:在求解过程中,但每次出现的子问题并不一定是新的问题,有些子问题被多次重复计算。 动态规划算法利用了这种子问题的重叠性质,每个子问题只计算一次,将其计算结果保存在一个表中,当需要再次计算计算完毕的子问题时,只需在表中简单地看一下结果,就可以获得较高的计算效率

提高警惕

首先,引用动态规划的经典问题,最长不降低子序列

其定义是在:中设定由n个不同整数构成的数列b[n],如果有下标$i_1的话

例如

13、7、9、16、38、24、37、18、44、19、21、22、63和15

有一个长度为1316384463的不下降的子串。

但是,观察结果显示,实际上有79161819212263长度为8的不下降子串,所以会有更长的不下降子串吗? 请找到最长的不下降子序列

输入格式

第一行为n,n个(n=100000 ),表示第二行为n个数值)数字之间用空格分开,在最后的数字末尾不能留下空格)。

输出格式

表示最长子序列长度的整数。

输入示例

4

1 3 1 2

输出示例

2

想法

当要求某一段的最优时,考虑如何求更短段的最优,看最短段的最优能否扩大推广到最大段的最优;

假设这样的表:

第3行表示该序列元素的可连接的最长的不下降子序列的长度,由于自身的长度为1,所以初始值全部为1

第4行表示形成与哪个数组元素链接最长不下降的子数组

从倒数第二项63开始计数,后面只有一项,所以只比较一次。 因为是6315,所以从63出发,不做任何链接。 长度果然是1。

看倒数第三项22,后面有两项,所以必须在这两项中找到大于22且长度最长的数值作为链接。 因为只有2263,所以将22的长度加上2,即与自己的长度链接的数值的长度,将链接位置修正为13,即63的下标。

如果你看倒数第四项21,你必须在这三项中找到一个大于21、长度最长的数值作为链接,注意:是长度。 因为很容易看出数值22满足了这个条件,所以将21的长度修正为3,将链接位置修正为12,即22的排列下标。

依次,最后结果如下表:所示

最终状态的迁移方程式为:$f(I )=max ) f ) j )1) b_j

代码

process.stdin.setencoding(UTF8 );

var arr=[];

var bool=0;

var n=0;

var longest=1;

var a=[];

var dp=[];

process.stdin.on('readable ',function ) )。

var chunk=process.stdin.read (;

if(chunk!==null ) {

ARR.push(chunk.Trim ) )

}

if(bool=2) {

n=arr[0];

process.stdin.Emit('end ' ) )。

}

布尔

);

process.stdin.on('end ',function ) {

a=ARR.Slice(1).join (' ).split (' ).map ) function ) index,elem ) {

return parseint (索引;

() )

for(letI=0; I

dp[i]=1;

}

for(letI=1; I

for(letj=0; Jj

if(a ) I ) a ) j ) )

dp[i]=math.max(DP[j]1,DP[I] ) )。

}

longest=math.max(DP[I],longest ) )。

}

}

console.log ('最长长度为:' longest );

process.stdout.write('end );

);

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。