http://shakeone-algo.spaces.live.com/blog/cns!3472D0BEEE09F329!131.entry
动态规划问题(8) -- 最大和子序列续
拓展问题“最大和子序列”
在一个长度为n的数列中,求m个连续子序列,使得这m个连续子序列的和最大,且m个子序列无公共元素.
设f(i,j)表示在前i个数中,一共有j个连续子序列的最大和.
则f(i,j) = max {f(i-1,j)+arr[i], f(k,j-1)+arr[i]}, 其中第二个式子表示前k个数中,一共有j-1个子序列,并且arr[i]属于最后一个子序列,而且这最后一个子序列的是从k+1到i,其中k属于[j-1,i-1],当k=i-1,表示arr[i]自成一个序列,当k=j-1,表示前j-1个子序列都是由一个数构成的.然后在取值范围内遍历所有变量i,j,k,得到所求为f(n,m).
代码:(网页中的代码有错误,下面贴出mtthew的代码):
![ContractedBlock.gif](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include
<
iostream
>
using namespace std;
#define MAXLENGTH 100
int f[MAXLENGTH][MAXLENGTH],a[MAXLENGTH];
int main(){
int n;
cin >> n;
int m;
cin >> m;
int i;
for (i = 1 ;i <= n;i ++ ){
cin >> a[i];
}
int j;
for (j = 1 ;j <= m;j ++ ){
for (i = j;i <= n;i ++ ){
f[i][j] = f[i - 1 ][j] + a[i];
for ( int k = j - 1 ;k < i;k ++ ){
if (f[k][j - 1 ] + a[i] > f[i][j]){
f[i][j] = f[k][j - 1 ] + a[i];
}
}
}
}
int best = - 1 ;
for (i = 1 ;i <= n;i ++ ){
if (best < f[i][m]){
best = f[i][m];
}
}
// 测试数据7 2 2 -3 6 -5 -3 9 5
cout << best << endl;
}
using namespace std;
#define MAXLENGTH 100
int f[MAXLENGTH][MAXLENGTH],a[MAXLENGTH];
int main(){
int n;
cin >> n;
int m;
cin >> m;
int i;
for (i = 1 ;i <= n;i ++ ){
cin >> a[i];
}
int j;
for (j = 1 ;j <= m;j ++ ){
for (i = j;i <= n;i ++ ){
f[i][j] = f[i - 1 ][j] + a[i];
for ( int k = j - 1 ;k < i;k ++ ){
if (f[k][j - 1 ] + a[i] > f[i][j]){
f[i][j] = f[k][j - 1 ] + a[i];
}
}
}
}
int best = - 1 ;
for (i = 1 ;i <= n;i ++ ){
if (best < f[i][m]){
best = f[i][m];
}
}
// 测试数据7 2 2 -3 6 -5 -3 9 5
cout << best << endl;
}