DP问题__最大m子段和问题m
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最后结果g[3]即为所 即为所 最后结果 求的最大m=3子段和 求的最大 子段和
初始化g[]中的元素为负无穷 初始化 中的元素为负无穷 (或者较大的负数 ,因为此 或者较大的负数), 或者较大的负数 时说明还不存在最优的情况
伪代码: 伪代码: MAXSUM(a,n,m) 1. let g[1..n] and f[1..n] be new arries 2. for i<-1 to n 3. g[i]<--INF //将g[],f[]两个数组初始化为极小负数,说明此 两个数组初始化为极小负数, 将 两个数组初始化为极小负数 4. f[i]<--INF //时还不存在最优的解 时还不存在最优的解 5. for i<-1 to n 6. t<-min(i,m) //由题意可分析得,m<=n,因此j不得大于 由题意可分析得, ,因此 不得大于t 由题意可分析得 不得大于 7. for j<-1 to t 8. f[j]<-max(f[j],g[j-1])+a[i] 9. g[j-1]<-max(g[j-1],f[j-1]) 10. g[j-1]<-max(g[j-1],f[j-1]) //获得 行时最大 子段和的最优值 获得i行时最大 获得 行时最大t子段和的最优值 11. print g[m]
DP问题分析 问题分析
——求解最大 字段和 求解最大m字段和 求解最大
最大m子段和问题:给定由 个整数 可能为负) 个整数( 最大 子段和问题:给定由n个整数(可能为负)组 子段和问题 成的序列a1、 、 以及一个正整数m, 成的序列 、a2、a3...,an,以及一个正整数 ,要求确定 以及一个正整数 序列的m个不相交子段 使这m个子段的总和最大 个不相交子段, 个子段的总和最大! 序列的 个不相交子段,使这 个子段的总和最大! 例如: 例如:序列为 2 3 -7 6 4 -5 那么这3个字段的总和最大为 那么这 个字段的总和最大为15 个字段的总和最大为
若要求的m=3 若要求的
若当m=1时,则该问题变为求最大字段和的问题 时 若当
1)当给定的序列中不含负数时,则所求最大字段和为给序 当给定的序列中不含负数时, 列之和。 列之和。 2)当给定的序列中存在负数时,则建立一个辅助数组对该 )当给定的序列中存在负数时, 序列进行求最大字段和
新建辅助数组b[],其中 表示以第i个元素结尾时的最大字段和 新建辅助数组 ,其中b[i]表示以第 个元素结尾时的最大字段和。 表示以第 个元素结尾时的最大字段和。 在求第i个数是否包含在最大字段和中时 个数是否包含在最大字段和中时, 在求第 个数是否包含在最大字段和中时,当b[i-1]>0时,b[i]=b[i时 1]+a[i],即包含其中。当b[i-1]<=0时,b[i]=a[i],即b[i]等于第 个元素 即包含其中。 等于第i个元素 即包含其中 时 , 等于第 本身。 本身。
i=5 f(1)=max(f(1),g(0))+a[5]=10 g(0)=max(g(0),f(0))=0 f(2)=max(f(2),g(1))+a[5]=15 g(1)=max(g(1),f(1))=10 f(3)=max(f(3),g(2))+a[5]=15 g(2)=max(g(2),f(2))=15 --------------------------------------------g(3)=max(g(3),f(3))=15 i=6 f(1)=max(f(1),g(0))+a[6]=5 g(0)=max(g(0),f(0))=0 f(2)=max(f(2),g(1))+a[6]=10 g(1)=max(g(1),f(1))=10 f(3)=max(f(3),g(2))+a[6]=10 g(2)=max(g(2),f(2))=15 --------------------------------------------g(3)=max(g(3),f(3))=15
例: a: 2 3 -7 6 4 -5 b: 2 5 -2 6 10 5 最大子段和为10
由此得出等式: 由此得出等式: b[i]=max{b[i-1]+a[i],a[i]}
而实际只要求保存b[i]的前一状态就可,随意可利用变量b代替数 的前一状态就可,随意可利用变量 代替数 而实际只要求保存 的前一状态就可 所以改进后伪代码如下: 组b[],所以改进后伪代码如下: 所以改进后伪代码如下
根据分析g(i,j)=max{g(i-1,j),f(i,j)}发现,g要么和前一个状态 发现, 要么和前一个状态 要么和前一个状态g(i-1,j) 根据分析 发现 相同,要么和此时所得的数f(i,j)相同。 相同。 相同,要么和此时所得的数 相同 同样的, 同样的,f(i,j)=max{f(i-1,j)+a[i],g(i-1,j-1)+a[i]}中,f-a[i]要么和前一个 中 要么和前一个 状态相同,要么和前一个最优解g相同 所以, 相同。 状态相同,要么和前一个最优解 相同。所以,我们可以用一维数组来 代替二维数组。 代替二维数组。 于是,当在第 行时 行时, 于是,当在第i行时, f(j)=max{f(j),g(j-1)}+a[i]. 此时在等式的第二个f(j)实际意义是在对行数 进行for循环时求得的 实际意义是在对行数i进行 此时在等式的第二个 实际意义是在对行数 进行 循环时求得的 最大的值。 则表示为对行数i进行 循环时求得的最大的值。 最大的值。而g(i-1)则表示为对行数 进行 循环时求得的最大的值。 则表示为对行数 进行for循环时求得的最大的值 所以f(j)表示为在第 行时,最大j子段和的值 包括a[i]). 表示为在第i行时 子段和的值(包括 所以 表示为在第 行时,最大 子段和的值 包括 同时,因为g[m]表示为最大 子段和的值,即为所求值,因此, 表示为最大m子段和的值 同时,因为 表示为最大 子段和的值,即为所求值,因此, g[j]=max(g[j],f[j]),它的意思说明第 行时的最大 子段和要么 行时的最大j子段和要么 ,它的意思说明第i行时的最大 等于之前的g的最优值 要么等于此时包含a[i]情况下的最优值 的最优值, 情况下的最优值f[j]. 等于之前的 的最优值,要么等于此时包含 情况下的最优值
j
0 1 0 2 5 5 6 10 10 0 0 5 -2 11 15 10 2 0 0 0 -2 11 15 10 3
例: a: 2 3 -7 6 4 -5 :
0 1
0 0 0 0 0
i
2 3
4 5 6 0 0
0
1 0 2 5 5 6 10 10 0 0 5 5 11 15 15
2 0 0 0 -2 11 15 15
i=3 f(1)=max(f(1),g(0))+a[3]=-2 g(0)=max(g(0),f(0))=0 f(2)=max(f(2),g(1))+a[3]=-2 g(1)=max(g(1),f(1))=5 f(3)=max(f(3),g(2))+a[3]=-2 g(2)=max(g(2),f(2))=5 --------------------------------------------g(3)=max(g(3),f(3))=-2 i=4 f(1)=max(f(1),g(0))+a[4]=6 g(0)=max(g(0),f(0))=0 f(2)=max(f(2),g(1))+a[4]=11 g(1)=max(g(1),f(1))=6 f(3)=max(f(3),g(2))+a[4]=11 g(2)=max(g(2),f(2))=11 --------------------------------------------g(3)=max(g(3),f(3))=11
伪代码: 伪代码:
MAXSUM(a,n) 1. b<-0 2. maxsum<-0 3. for i<-1 to n 4. if b>0 5. b<-b+a 6. else 7. b<-a 8. if b>maxsun 9. maxsum<-b 10.return maxsum
当m>1时 时 表示前i个元素 必定包含第i个元素 分为互不相交的j段所得 设f(i,j)表示前 个元素 必定包含第 个元素 分为互不相交的 段所得 表示前 个元素(必定包含第 个元素)分为互不相交的 的最大j子段和 子段和(f(i,j)不一定是最优最大 子段和 ,并且 不一定是最优最大j子段和 的最大 子段和 不一定是最优最大 子段和),并且j<=i。 。 因此在考虑第i个元素时 可能存在两种情况: 个元素时, 因此在考虑第 个元素时,可能存在两种情况: 1)第i个元素和前一个元素一起包含在第 段中; 个元素和前一个元素一起包含在第j段中 ) 个元素和前一个元素一起包含在第 段中; 2)第i个元素独自划分在第 段中。 个元素独自划分在第j段中 ) 个元素独自划分在第 段中。 根据DP问题的分析 问题的分析, 根据 问题的分析, 1)f(i-1,j)表示第 个元素的最大 子段和,所以 表示第i-1个元素的最大 子段和, ) 表示第 个元素的最大j子段和 所以f(i,j)=f(i-1,j)+a[i]. 2)max{f(k,j-1)}其中 其中k=j-1..i-1.即表示为在第 个元素之前得到的 即表示为在第i个元素之前得到的 ) 其中 即表示为在第 j-1个子段之和的最优选择。所以 个子段之和的最优选择。 其中k=j-1..i-1. 个子段之和的最优选择 所以f(i,j)=max{f(k,j-1)+a[i]},其中 其中 综上: 其中k=j-1..i-1. 综上:f(i,j)=max{f(i-1,j)+a[i],f(k,j-1)+a[i]},其中 其中
例: a: 2 3 -7 6 4 -5 i=1 f(1)=max(f(1),g(0))+a[1]=2 g(0)=max(g(0),f(0))=0 --------------------------------------------g(1)=max(g(1),f(1))=2 i=2 f(1)=max(f(1),g(0))+a[2]=5 g(0)=max(g(0),f(0))=0 f(2)=max(f(2),g(1))+a[2]=5 g(1)=max(g(1),f(1))=5 --------------------------------------------g(2)=max(g(2),f(2))=5
3
Βιβλιοθήκη Baidu
0 0 0 0 0
即得到表格如右图所示: 即得到表格如右图所示: 所以g[n][m]就是最大 子段 就是最大m子段 所以 就是最大 和。
4 5 6 0 0
因此,根据设置的辅助数组 因此,根据设置的辅助数组g[][],我们重新可以定义 ,我们重新可以定义f(i,j),而此次定 而此次定 方程将是基于储存最优解值的g[][]数组得到的。 数组得到的。 义的 f(i,j)方程将是基于储存最优解值的 方程将是基于储存最优解值的 数组得到的 同样的, 的定义中也存在两种可能性: 同样的,在f(i,j)的定义中也存在两种可能性: 的定义中也存在两种可能性 1)第i个元素和前一个元素一起包含在第 段中; 个元素和前一个元素一起包含在第j段中 ) 个元素和前一个元素一起包含在第 段中; 2)第i个元素独自划分在第 段中。 个元素独自划分在第j段中 ) 个元素独自划分在第 段中。 其中的第二种情况, 表示max{f(k,j-1)}其中 其中k=j-1..i-1.它的意 其中的第二种情况,用g(i-1,j-1)表示 表示 其中 它的意 义是说明前i-1个元素的最大 子段和为g(i-1,j-1),而前 个元素的最大 个元素的最大j-1子段和为 而前i个元素的最大 义是说明前 个元素的最大 子段和为 而前 个元素的最大j 子段和为g(i-1,j-1)+a[i]. 子段和为 综上: 综上: f(i,j)=max{f(i-1,j)+a[i],g(i-1,j-1)+a[i]}. 又因为 g(i,j)=max{g(i-1,j),f(i,j)}. 将是最后结果, 子段和。 所以 g(n,m)将是最后结果,即最优的最大 子段和。 将是最后结果 即最优的最大m子段和
3
因为f(i,j)表示前 个元素的最大 0 表示前i个元素的最大 因为 表示前 j子段和,并且必定包含第 个元素, 子段和, 个元素, 子段和 并且必定包含第i个元素 1 这显然不一定是最优的。 这显然不一定是最优的。因此设 g(i,j)表示前 个元素最大 子段和, 表示前i个元素最大 子段和, 表示前 个元素最大j子段和 其不一定包含第i个元素 个元素。 其不一定包含第 个元素。 2 由此我们可知: 由此我们可知: g(i,j)=max{g(i-1,j),f(i,j)}.