动态规划--最长不降子序列

 问题:给定一个序列,找出最长不将子序列,比如序列[3,18,7,14,10,12,23,41,16,24]的最长不将子序列是[3,7,10,12,23,41]。

 

解法:

对于我来说,一般一个解题的过程都会分好几个阶段,因为大脑计算的能力限制,第一个阶段中总是以完成任务为目标,也就是

用最少的程序的时间来完成,当然这时候就需要选择最为简单的解决方法:

 

(1)穷举法:

假设有一个函数max_incr_seq(a, i, j),其功能是求出序列a中的从下标i到j的子序列(连续)的最长不将子序列,那么整个求解

过程可以用下面的伪代码来完成:

 

max_seq = [] /**空序列*/

 

for (i = 0; i < N; ++i)

{

for (j = i; j < N; ++j)

{

seq = max_incr_seq(a, i, j);

if seq > max_seq

{

max_seq = seq

}

}

 

return max_seq

 

很明显这个算法很慢,因为函数max_incr_seq的本身至少要O(N)的复杂度,而这个实现中又带有两层循环,那么复杂度至少为O(N^3)

如果我们仔细观察上面的实现,会发现有很多冗余的地方,也就是计算又再次计算,这时候思路就应该转到如果利用已经计算好的结果来

进行下次计算。

当然要达到这个目的的话就应该有这么一个公式:S[i - 1, j] = f(S[i, j], a[i - 1]),其中S[i, j]表示a[i..j]中的最长不将子序列,再进一步的考虑,其实这时候就可以发现S[0, N-1] = f(S[1, N-1], a[0])。这里我们假设上述公式是存在的,可以得到以下伪代码:

for(i = N - 1; i >= 1; --i)

{

if (i == N - 1)

{

S[i, N - 1] = a[i]

}

 

S[i - 1, N - 1] = f(S[i, N -1])

}

 

好的,这样的方法确实是能够求出S[0, N-1],但是求解函数f似乎变成一个艰巨的任务,为了节省时间和保证正确性,我们就得利用

现有的成熟的理论做为指导了,对于上述的实现给我么一个启发就是每次计算只做一次,并且这个计算的结果可以作为下次计算的输入。

 

(2)递归法:

在我们决定使用递归法的时候我们最需要考虑的就是...[未完待续]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值