动态规划问题整理

合集下载

动态规划资源分配问题

动态规划资源分配问题

S1
7
X1
12
3
4
P1(x1)
44
5
8
F2+ p1 21 19
17 18
f1(s1)
21
X1*
1
• 当k=2时;
f2(s2) = max [p2(x2)+ f3(s3) ]
1< x2 < s2 3< s2< 6 计算结果:
S2 X2 p2(x2) F3+ p2 f2(s2) X2*
34 1 12 3 35 10 12 12 10 12 1 1或2
f(k* sk ) max{ fk (sk , xk )}
xk 1,2,3...,sk
4
xi sk
ik
xi大于等于1且为整数
将递推关系写出即是
f
* k
(
sk
)
xk
max
1, 2 ,..., sk
{Pk
(
xk
)
f
* k 1
(
sk
xk )}
f(5* s5)=0
k 1,2,3
当k=4时;
f4(s4) = max [p4(x4)]
S3 X3 p3(x3) F3+ p3 f3(s3) X3*
23 1 12 5 56 7 98 79 11
4 123 568 12 10 10 12 1
5 1 2 34 5 6 88 13 13 12 10 13 1或2
• 当k=1时;
f1(s1) = max [p1(x1)+ f2(s2) ]
1< x1< s1 s1=7 计算结果:
5 123 35 6 15 14 13 15 1

动态规划47题

动态规划47题

动态规划练习【题目一览】总分【问题描述】学生在我们USACO的竞赛中的得分越多我们越高兴。

我们试着设计我们的竞赛以便人们能尽可能的多得分,这需要你的帮助。

我们可以从几个种类中选取竞赛的题目,这里的一个“种类”是指一个竞赛题目的集合,解决集合中的题目需要相同多的时间并且能得到相同的分数。

你的任务是写一个程序来告诉USACO的职员,应该从每一个种类中选取多少题目,使得解决题目的总耗时在竞赛规定的时间里并且总分最大。

输入包括竞赛的时间M(1<=M<=10000)(不要担心,你要到了训练营中才会有长时间的比赛)和“种类”的数目N(1<=N<=10000)。

后面的每一行将包括两个整数来描述一个“种类”:第一个整数说明解决这种题目能得的分数(1<=points<=10000),第二整数说明解决这种题目所需的时间(1<=minutes<=10000)。

你的程序应该确定我们应该从每个“种类”中选多少道题目使得能在竞赛的时间中得到最大的分数。

来自任意的“种类”的题目数目可能任何非负数(0或更多)。

计算可能得到的最大分数。

【输入格式】输入文件中的第1行:M,N--竞赛的时间和题目“种类”的数目。

第2~N+1行:两个整数:每个“种类”题目的分数和耗时。

【输出格式】输出文件中仅一行,包括那个在给定的限制里可能得到的最大的分数。

【输入输出样例】输入:300 4100 60250 120120 10035 20输出:605从第2个“种类”中选两题第4个“种类”中选三题。

邮票【问题描述】已知一个N枚邮票的面值集合(如,{1分,3分})和一个上限K——表示信封上能够贴K张邮票。

计算从1到M的最大连续可贴出的邮资。

例如,假设有1分和3分的邮票;你最多可以贴5张邮票。

很容易贴出1到5分的邮资(用1分邮票贴就行了),接下来的邮资也不难:6 = 3 + 37 = 3 + 3 + 18 = 3 + 3 + 1 + 19 = 3 + 3 + 310 = 3 + 3 + 3 + 111 = 3 + 3 + 3 + 1 + 112 = 3 + 3 + 3 + 313 = 3 + 3 + 3 + 3 + 1然而,使用5枚1分或者3分的邮票根本不可能贴出14分的邮资。

动态规划算法详解及经典例题

动态规划算法详解及经典例题

动态规划算法详解及经典例题⼀、基本概念(1)⼀种使⽤多阶段决策过程最优的通⽤⽅法。

(2)动态规划过程是:每次决策依赖于当前状态,⼜随即引起状态的转移。

⼀个决策序列就是在变化的状态中产⽣出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。

假设问题是由交叠的⼦问题所构成,我们就能够⽤动态规划技术来解决它。

⼀般来说,这种⼦问题出⾃对给定问题求解的递推关系中,这个递推关系包括了同样问题的更⼩⼦问题的解。

动态规划法建议,与其对交叠⼦问题⼀次重新的求解,不如把每⼀个较⼩⼦问题仅仅求解⼀次并把结果记录在表中(动态规划也是空间换时间的)。

这样就能够从表中得到原始问题的解。

(3)动态规划经常常使⽤于解决最优化问题,这些问题多表现为多阶段决策。

关于多阶段决策:在实际中,⼈们经常遇到这样⼀类决策问题,即因为过程的特殊性,能够将决策的全过程根据时间或空间划分若⼲个联系的阶段。

⽽在各阶段中。

⼈们都须要作出⽅案的选择。

我们称之为决策。

⽽且当⼀个阶段的决策之后,经常影响到下⼀个阶段的决策,从⽽影响整个过程的活动。

这样,各个阶段所确定的决策就构成⼀个决策序列,常称之为策略。

因为各个阶段可供选择的决策往往不⽌⼀个。

因⽽就可能有很多决策以供选择,这些可供选择的策略构成⼀个集合,我们称之为同意策略集合(简称策略集合)。

每⼀个策略都对应地确定⼀种活动的效果。

我们假定这个效果能够⽤数量来衡量。

因为不同的策略经常导致不同的效果,因此,怎样在同意策略集合中选择⼀个策略,使其在预定的标准下达到最好的效果。

经常是⼈们所关⼼的问题。

我们称这种策略为最优策略,这类问题就称为多阶段决策问题。

(4)多阶段决策问题举例:机器负荷分配问题某种机器能够在⾼低两种不同的负荷下进⾏⽣产。

在⾼负荷下⽣产时。

产品的年产量g和投⼊⽣产的机器数量x的关系为g=g(x),这时的年完善率为a,即假设年初完善机器数为x,到年终时完善的机器数为a*x(0<a<1);在低负荷下⽣产时,产品的年产量h和投⼊⽣产的机器数量y 的关系为h=h(y)。

动态规划例题

动态规划例题

动态规划例题动态规划是一种以最优化原理为基础的问题求解方法,通过拆分问题为若干阶段,每个阶段求解一个子问题,再逐步推导出整个问题的最优解。

例如,有一个背包能够承受一定的重量,现有一些物品,每个物品都有自己的重量和价值。

我们希望将物品放入背包中,使得背包的总价值最大。

这个问题可以用动态规划来解决。

首先,我们定义一个二维数组dp,其中dp[i][j]表示在前i个物品中,容量为j的背包中所能放入的物品的最大价值。

那么,对于每一个物品,可以选择放入背包或者不放入背包。

如果选择放入背包,最大价值为dp[i-1][j-w[i]] + v[i],其中w[i]表示第i个物品的重量,v[i]表示第i个物品的价值。

如果选择不放入背包,最大价值为dp[i-1][j]。

因此,dp[i][j]的状态转移方程为:dp[i][j] = max(dp[i-1][j-w[i]] + v[i], dp[i-1][j])。

基于这个状态转移方程,可以逐步求解从第1个物品到第n个物品的最大价值。

最终,dp[n][W]即为问题的最优解,其中W 表示背包的容量。

举个简单的例子,假设背包的容量为10,有3个物品,它们的重量分别为3、4、5,价值分别为4、5、6。

此时,可以得到如下的dp矩阵:0 0 0 0 0 0 0 0 0 0 00 0 0 4 4 4 4 4 4 4 40 0 0 4 5 5 9 9 9 9 90 0 0 4 5 5 9 10 10 14 14我们可以看到,dp[3][10]的最大价值为14,表示在前3个物品中,容量为10的背包中所能放入的物品的最大价值为14。

通过动态规划,我们可以有效地求解背包问题,得到物品放入背包的最优解。

这个例子只是动态规划的一个简单应用,实际上,动态规划可以解决各种复杂的问题,如最长公共子序列、最大子数组和、最大字段和等。

因此,学习动态规划是非常有意义的。

动态规划问题常见解法

动态规划问题常见解法

动态规划问题常见解法
动态规划是一种高效解决优化问题的方法。

它通常用于涉及最
优化问题和最短路径的计算中。

下面是一些常见的动态规划问题解法:
1. 背包问题
背包问题是动态规划中的经典问题之一。

其目标是在给定的背
包容量下,选择一些物品放入背包中,使得物品总价值最大。

解决
这个问题的常见方法是使用动态规划的思想,定义一个二维数组来
记录每个物品放入背包时的最大价值,然后逐步计算出最终的结果。

2. 最长公共子序列问题
最长公共子序列问题是寻找两个字符串中最长的公共子序列的
问题。

解决这个问题的常见方法是使用动态规划的思想,定义一个
二维数组来记录两个字符串中每个位置的最长公共子序列的长度。

然后通过递推关系来计算出最终的结果。

3. 矩阵链乘法问题
矩阵链乘法问题是计算一系列矩阵相乘的最佳顺序的问题。


决这个问题的常见方法是使用动态规划的思想,定义一个二维数组
来记录每个矩阵相乘时的最小乘法次数,然后逐步计算出最终的结果。

4. 最长递增子序列问题
最长递增子序列问题是寻找一个序列中最长的递增子序列的问题。

解决这个问题的常见方法是使用动态规划的思想,定义一个一
维数组来记录每个位置处的最长递增子序列的长度,然后通过递推
关系来计算出最终的结果。

以上是一些常见的动态规划问题解法。

通过灵活运用这些方法,我们可以更高效地解决优化问题和最短路径计算等相关任务。

动态规划习题完整版

动态规划习题完整版

动态规划习题Document serial number【NL89WT-NY98YT-NC8CB-NNUUT-NUT108】动态规划专题分类视图数轴动规题:题1.2001年普及组第4题--装箱问题【问题描述】有一个箱子容量为V(正整数,0≤V≤20000),同时有n个物品(0<n≤30),每个物品有一个体积(正整数)。

要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

【输入格式】输入文件box.in有若干行。

第一行:一个整数,表示箱子容量V;第二行:一个整数,表示物品个数n;接下来n行,分别表示这n个物品的各自体积。

【输出格式】输出文件box.out只有一行数据,该行只有一个数,表示最小的箱子剩余空间。

【输入样例】2468312797【输出样例】题2.1996年提高组第4题--砝码秤重__数据加强版【问题描述】设有n种砝码,第k种砝码有Ck 个,每个重量均为Wk,求:用这些砝码能秤出的不同重量的个数,但不包括一个砝码也不用的情况。

【输入格式】输入文件weight.in的第一行只有一个数n,表示不同的砝码的种类数.第2行至第n+1行,每行有两个整数.第k+1行的两个数分别表示第k种砝码的个数和重量.【输出格式】输出文件weight.out中只有一行数据:Total=N。

表示用这些砝码能秤出的不同重量数。

【输入样例】22223【输出样例】Total=8【样例说明】重量2,3,4,5,6,7,8,10都能秤得【数据限制】对于100%的数据,砝码的种类n满足:1≤n≤100;对于30%的数据,砝码的总数量C满足:1≤C≤20;对于100%的数据,砝码的总数量C满足:1≤C≤100;对于所有的数据,砝码的总重量W满足:1≤W≤400000;题3.石子归并-szgb.pas【问题描述】有一堆石头质量分别为W1,W2,…,Wn.(Wi≤10000),将石头合并为两堆,使两堆质量的差最小。

【输入】输入文件szgb.in的第一行只有一个整数n(1≤n≤50),表示有n堆石子。

动态规划总结经典题目(经典中的经典)

动态规划总结经典题目(经典中的经典)

动态规划总结——经典问题总结本文着重讨论状态是如何表示,以及方程是怎样表示的。

当然,还附上关键的,有可能作为模板的代码段。

但有的代码的实现是优化版的。

经典问题总结最长上升子序列(LIS)问题描述如下:设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。

求最大的m值。

这里采用的是逆向思维的方法,从最后一个开始想起,即先从A[N](A数组是存放数据的数组,下同)开始,则只有长度为1的子序列,到A[N-1]时就有两种情况,如果a[n-1] < a[n] 则存在长度为2的不下降子序列a[n-1],a[n];如果a[n-1] > a[n] 则存在长度为1的不下降子序列a[n-1]或者a[n]。

有了以上的思想,DP方程就呼之欲出了(这里是顺序推的,不是逆序的):DP[I]=MAX(1,DP[J]+1)J=0,1,...,I-1但这样的想法实现起来是)O(n^2)的。

本题还有更好的解法,就是O(n*logn)。

利用了长升子序列的性质来优化,以下是优化版的代码://最长不降子序const int SIZE=500001;int data[SIZE];int dp[SIZE];//返回值是最长不降子序列的最大长度,复杂度O(N*logN)int LCS(int n) { //N是DATA数组的长度,下标从1开始int len(1),low,high,mid,i;dp[1]=data[1];for(i=1;i<=n;++i) {low=1;high=len;while( low<=high ) { //二分mid=(low+high)/2;if( data[i]>dp[mid] ) {low=mid+1;}else {high=mid-1;}}dp[low]=data[i];if( low>len ) {++len;}}return len;}最长公共子序列(LCS)给出两个字符串a, b,求它们的最长、连续的公共字串。

动态规划和几个经典问题

动态规划和几个经典问题

动态规划和⼏个经典问题动态规划 (本⽂适合⼊门理解思想,后期多刷题) 动态规划是运筹学的⼀个分⽀,是求解多阶段决策过程最优化问题的数学⽅法,在经济管理、⼯程技术、⼯农业⽣产及军事部门中都有着⼴泛的应⽤,并且获得了显著的效果。

学习动态规划,我们⾸先要了解多阶段决策问题。

多阶段决策问题例⼦: ⽣产决策问题:企业在⽣产过程中,由于需求是随时间变化的,因此企业为了获得全年的最佳⽣产效益,就要在整个⽣产过程中逐⽉或逐季度地根据库存和需求决定⽣产计划。

机器负荷分配问题:某种机器可以在⾼低两种不同的负荷下进⾏⽣产。

要求制定⼀个五年计划,在每年开始时,决定如何重新分配完好的机器在两种不同的负荷下⽣产的数量,使在五年内产品的总产量达到最⾼。

航天飞机飞⾏控制问题:由于航天飞机的运动的环境是不断变化的,因此就要根据航天飞机飞⾏在不同环境中的情况,不断地决定航天飞机的飞⾏⽅向和速度(状态),使之能最省燃料和完成飞⾏任务(如软着陆)。

多阶段决策过程的特点: 根据过程的特性可以将过程按空间、时间等标志分为若⼲个互相联系⼜互相区别的阶段。

在每⼀个阶段都需要做出决策,从⽽使整个过程达到最好的效果。

各个阶段决策的选取不是任意确定的,它依赖于当前⾯临的状态,⼜影响以后的发展。

当各个阶段的决策确定后,就组成了⼀个决策序列,因⽽也就决定了整个过程的⼀条活动路线,这样的⼀个前后关联具有链状结构的多阶段过程就称为多阶段决策问题。

针对多阶段决策过程的最优化问题,美国数学家Bellman等⼈在20世纪50年代初提出了著名的最优化原理,把多阶段决策问题转化为⼀系列单阶段最优化问题,从⽽逐个求解,创⽴了解决这类过程优化问题的新⽅法:动态规划。

对最佳路径(最佳决策过程)所经过的各个阶段,其中每个阶段始点到全过程终点的路径,必定是该阶段始点到全过程终点的⼀切可能路径中的最佳路径(最优决策),这就是Bellman提出的著名的最优化原理。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

动态规划:【1】.矩阵乘法链,最小乘法次数。

一、问题描述给定一个矩阵序列<A1,A2,…,An>,计算乘积A1A2…An。

要求找出一个加全部括号的方式,使得标量乘法的次数最小。

对于任意两个矩阵AiAi+1相乘,其乘法次数为pi-1pi pi+1,不同的加全部括号,所需要的乘法次数可能相差很大。

假设现在有三个矩阵A1A2A3相乘,维数分别为:10×100,100×5,5×50。

1、如果我们采用如下方式加全部括号:((A1A2)A3)则首先计算(A1A2),乘法次数为p0p1 p2,得到新矩阵的维数为p0×p2计算((A1A2)A3),乘法次数为p0p2 p3,总的计算次数为p0p1 p2+ p0p2 p3=10×100×5+10×5×50=75002、如果我们采用如下方式加全部括号:(A1(A2 A3))则首先计算(A2 A3),乘法次数为p1 p2 p3,得到新矩阵的维数为p1×p3计算(A1(A2 A3)),乘法次数为p0p1 p3,总的计算次数为p1 p2 p3+ p0p1 p3=100×5×50+10×100×50=75000第二种方式需要的次数是第二次的10倍!二、问题分析:由前面可知,一个序列如果只有一个矩阵,则只有一种方式加全部括号,如果有两个或两个以上的矩阵,则必然可以看做两个子序列的乘积,且这两个子序列也是加全部括号。

我们用cost(i,j)表示序列Ai…Aj在最优加全部括号时的标量乘积次数,则其中p(i-1)p(k) p(j)为子序列Ai…Ak与Ak+1…Aj相乘时的标量相乘次数。

顺序连城可以把最后一个单个的看成单独加括号。

三、问题求解每一对满足1≤i≤j≤n的i和j都对应原问题的一个子问题,子问题个数为动态规划(二):矩阵链乘法,其中第一项表示i<j时的子问题个数,后一项表示i=j 时的子问题个数。

如果采用递归方法求解,则每个子问题都会被求解多次,可以保留中间结果。

另外我们也采用自底向上的动态规划方式求解。

首先定义一个二维矩阵value,value[i][j]存放子序列Ai…Aj在最优加全部括号时的标量乘积次数,我们只使用j>=i的部分,且value[i][i]=0。

动态规划的实现步骤如下:步骤一:令step=0;步骤二:对于所有i=0,…,n,计算并保存value[i][i+step];步骤三:若step=n-1,则结束,否则step=step+1,返回步骤二。

矩阵维数A130×35A235×15A315×5A45×10A510×20A620×25//实现思想:1.令step不同,即(j-i)不同;2.从i到j选择不同的分割点k。

i =< k < j;求出极大值。

记录分割的位置。

三重循环,从底层开始;首先分析:step=1,得到组合(1,2)、(2,3)、(3,4)、(4,5)、(5,6);step=2,得到组合(1,3)、(2,4)、(3,5)、(4,6);而其中,step=2,要用到不同的k了。

(1,2)3或者1(2,3);同理step=3,得到组合(1,4)、(2,5)、(3,6);要用到不同的k了。

1(2,3,4)或者(1,2)(3,4)或者(1,2,3)4;这些都是step 为小的时候得到的。

最终得到的step=5,得到组合(1,6)。

才是我们需要的。

【2】.装配线调度问题。

现有两条装配线,Sij表示第i条上完成第j道工序的装配站。

汽车完成组装需要依次完成1~n工序。

请找出完成装配并离开装配线的最快路线。

符号说明:ei:汽车进入装配线i的时间,i=1,2xi:汽车离开装配线i的时间aij:在装配站Sij完成装配需要的时间tij:在装配站Sij完成后离开第i条装配线,进入另一条装配线需要的转移时间注意,如果完成工序后,下一个工序还在同一条装配线上,则不需要转移时间。

问题求解:用Fij表示在第i条装配线上完成第j道工序的最快时间,用F表示完成汽车装配并离开装配线的时间,如果知道F1n和F2n,则有:要求出F1n和F2n,需要知道F1n-1和F2n-1,则有故得到递推公式:2、动态规划如果我们不是从上到下求解,而是从下到上求解,求解结果在某个地方保存起来,则可以大大改善求解速度。

这里的动态min只有两个部分,只有一个存在递归的形式,而上面哪一个却又两个递归的部分。

// 同理递增也是一样的,动态规划,甚至更简单写,由于只是自身的记录。

而公共的则是两个。

原理都是动态规划的。

【3】.最长公共子序列问题和编辑距离问题。

longest common subsequence。

子序列是不要求连续相等的字符序列。

这个问题也是算法导论上提过的问题。

注意这个问题是Subsequence不是Substring。

substring的话就是子串,子串的要求的连续相等的字符序列,而subsequence不要求连续。

比如说ABCD和ABD。

他们的longest common subsequence就是ABD。

而Longest common substring就是AB。

这个问题和Edit Distance是同样的一类问题。

解决这类的问题都是从一个优化的子结构开始得到递推式,从而给出一个一般的全局优化结构的过程。

在这里,我们假定两个字符串分别是S1和S2。

他们的长度是m和n。

我们用M[i,j]来表示一个长度为i的S1和长度为j的S2的最优方案。

我们要找的就是当M[m,n]是的方案。

问题的关键就是要找到M[i,j]和之前的那些诸如M[1..i, 1..j]之间的关系。

// m*n;我们把问题分成两种情况来讨论:1. 如果S1[i] == S2[j]。

就是i,j对应位置上的字符相等。

那么可以得出M[i,j] = M[i-1,j-1]+1;为什么呢?可以想象的。

如果M[i-1,j-1]也是一个最后方案,在这个最优方案上我们同时增加一个字符。

而这两个字符又相等。

那么我们只需要在这个M[i-1,j-1]的最优方案上++就可以了。

2. 如果S1[i] != S2[j]。

那么就拿M[i-1,j]和M[i,j-1]来比较。

M[i,j]的值就是M[i-1,j]和M[i,j-1]中大的值。

这好比原来的字符串是S1[1...i-1]是ABC,S2[1...j-1]是ABE。

那S1[1..i]是ABCE,S2[1..j]是ABEC。

可以看出来这个时候M[i,j]不是由M[i-1,j-1]决定的,而是由ABCE和ABE或者ABC和ABEC来决定的,也就是M[i-1,j]和M[i,j-1]。

所以我们可以把这个问题的递归式写成:【4】.编辑距离。

问题抽象归类:(编辑距离问题)设A和B是2个字符串。

要用最少的字符操作将字符串A转换为字符串B。

这里所说的字符操作包括:(1)删除一个字符;(2)插入一个字符;(3)将一个字符改为另一个字符。

将字符串A变换为字符串B所用的最少字符操作数称为字符串A到B的编辑距离,记为d(A,B)。

试设计一个有效算法,对任给的2个字符串A和B,计算出它们的编辑距离d(A,B)。

这个问题是动态规划中非常基础的一个问题,这个问题其实和另一个前面提到的问题很类似。

就是Edit Distance的问题。

编辑距离问题:Edit Distance问题又被成为Levenshtein distance问题。

这里的问题描述的就是两个字符串经过若干次修改(添加字符,删除字符,替换字符)变为两个完全相等字符串。

这里的distance就是指最少的修改次数。

其实这个也就是《编程之美》中的那个字符串相似度的问题。

相似的,我们还是定义一个M[i,j]的二维模型。

这时候一样还是分析M[i,j]的递归式。

这里的结果还是比较相近的。

如果S1[i] == S2[j]。

那么M[i,j]就等于M[i-1,j-1],就是说在S1[i]==S2[j]的情况下M[i,j]不会发生变化,显然不需要做什么改动。

edit(i, j) = edit(i-1, j-1);如果S1[i] != S2[j]的时候,那么就是M[i-1,j-1],M[i-1,j]和M[i,j-1]来做比较,我们取最小的那个值+1就可以了。

这里的M[i-1,j-1],M[i-1,j]和M[i,j-1]对应了添加、删除、替换这些操作。

M[i-1,j-1]可以替换最后一个S1[i]和S[j]来完成,而M[i-1,j]可以通过添加S1[i]来完成匹配。

edit(i, j) = min{edit(i-1, j)+1, edit(i, j-1)+1, edit(i-1, j-1)+1}对应添加,删除和替换这三个操作。

【5】.最长递增子序列(longest increase subsequence)既然已经说到了最长公共子序列,就把这个递增子序列也说了。

同样的,这里subsequence表明了这样的子序列不要求是连续的。

比如说有子序列{1, 9, 3, 8, 11,4, 5, 6, 4, 19, 7, 1, 7 }这样一个字符串的的最长递增子序列就是{1,3,4,5,6,7}或者{1,3,4,5,6,19}。

其实这个问题和前面的最长公共子序列问题还是有一定的关联的。

假设我们的初始的序列S1。

那我们从小到大先排序一下。

得到了S1'。

这样我们再求S1和S1'的最长公共子序列就可以知道答案了:)是不是有点巧妙啊。

这个过程还是比较直观的。

但是这个不是这次要说的重点,这个问题有比较传统的做法的:我们定义L(j)是一个优化的子结构,也就是最长递增子序列.那么L(j)和L(1..j-1)的关系可以描述成:L(j) = max{1; L(i)+1, (Ai<Aj)}; 所有的i<j;也就是说L(j)等于之前所有的L(i)中最大的的L(i)加一.这样的L(i)需要满足的条件就是Ai<Aj.这个推断还是比较容易理解的.就是选择j之前所有的满足小于当前数组的最大值.这里说满足无后效性。

即是前一阶段按照一定的次序排列好之后,对于某个给定阶段的状态来说,它以前各阶段的状态无法直接影响它未来的决策,只能间接地通过当前状态来影响。

比如一次为例如果有1,-1,2,-3,4,-5,6,-7.当i=3时。

前面有两个递增序列为(1,2)和(-1,2),长度都为2,这里2前面是1还是-1对求后面的递增序列没有直接的影响。

无后效。

上式子的意思即是,如果对所有的Aj>Ai,那么第i个元素可以直接接在L(i)子序列之后构成一个更长的子序列。

相关文档
最新文档