/*
name:
author:
date: 23-03-17 08:08
description:
【問題描述】----最大m子段和問題
給定由 n個整數(可能為負整數)組成的序列a1,a2,a3,……,an,以及乙個正整數 m,要求確定序列 a1,a2,a3,……,an的 m個不相交子段,
使這m個子段的總和達到最大,求出最大和。
演算法思路:
經典的動態規劃優化的問題。設f(i, j)表示前i個數劃分成j段,且包括第i個數的最大m子段和,那麼有dp方程:
f(i, j) = max (k = j - 1 ... i - 1) }
也就是說第i個數要麼自己劃到第j段,要麼和前乙個數一起劃到第j段裡面,轉移是o(n)的,總複雜度o(n * n * m)。
演算法1:int maxmsubsum(int i, int j);//自頂向下的備忘錄演算法
設定乙個備忘錄陣列b[m+1][n+1],b[i][j]表示把總長度為j的序列分成i個子段後,這i個子段的總和(其中第i個子段包含元素a[j-1])
利用原問題的遞迴關係,使用遞迴函式來求解。最後遍歷b[m][j],找出最優解。
演算法2:int maxmsubsum_2(int m, int n);//自底向上的動態規劃演算法
從i=1開始,依次記錄每乙個b[i][j],最後獲得最大規模的b[m][n]。
和演算法1一樣,最後遍歷b[m][j],找出最優解。
演算法3:int maxmsubsum_3(int m, int n);//優化的動態規劃演算法
與更早的資料沒有關係,於是可以用兩個一維陣列 maxsum[n+1] 和 cursum[n+1]代替b[m+1][n+1]。
最後寫了乙個函式 void printsubque(int m, int n); //查詢第i段連續子串行的左右邊界,並輸出這些子串行,
該函式需要用到備忘錄陣列b[m+1][n+1],故只能對演算法1和演算法2產生的結果有效。
*/#include#includeusing namespace std;
int maxmsubsum(int i, int j);//自頂向下的備忘錄演算法
int maxmsubsum_2(int m, int n);//自底向上的動態規劃演算法
int maxmsubsum_3(int m, int n);//優化的動態規劃演算法
void printsubque(int m, int n); //查詢第i段連續子串行的左右邊界,並輸出這些子串行
const int inf = -999999; //自定義的無窮小
const int m = 3;
const int n = 7;
int a[n] = ;
//int a[n] = ;
int b[m+1][n+1];
int main(int argc, char **argv)
maxmsubsum(m, n);
// maxmsubsum_2(m, n);
int max = b[m][1];
for (int j=2; j<=n; j++)
cout << max << endl;
printsubque(m, n);
//max = maxmsubsum_3(m, n);
// cout << max << endl;
system("pause");
return 0;
}int maxmsubsum(int i, int j)//備忘錄演算法
else
} //更新prem[j],為處理下一行做準備
maxsum[i] = cursum[i];
for (int j=i+1; j<=n; j++)
// cout << i << ": ";
// for (int j=1; j<=n; j++)
// cout << maxsum[j] << " ";
// cout << endl;
}
return maxsum[n];
} void printsubque(int m, int n)//查詢第i段連續子串行的左右邊界,並輸出這些子串行
; int r[m+1] = ;
int max;
int left, right;
for (int i=m,j=n; i>0; i--,j=left-1)
} left = right; //查詢第i段連續子串行的左邊界
while (b[i][left-1] > b[i-1][left-1] && left > 1)
l[i] = left;
r[i] = right; }
for (int i=1; i<=m; i++) //輸出m段子序列
cout << ")" << endl;
}}
最大m子段和問題
最大m子段和問題 給定由n個整數 可能為負數 組成的序列a1,a2 an 以及乙個正整數m,要求確定a1,a2 an 的m個不相交子段,使m個子段和達到最大。設b i,j 表示陣列a的前j項中i個子段的和的最大值,且第i個子段含a j 1 i m,i j n 則所求最優值為 與最大子段和問題類似,計...
最大m子段和
最大m子段和問題 給定由n個整數 可能為負 組成的序列a1 a2 a3.an,以及乙個正整數m,要求確定序列的m個不想交子段,使這m個子段的總和最大!設b i,j 表示陣列a的前j項中i個子段和的最大值,並且第i個子段包含a j 1 i m,i j n 則所求的最優值為maxb m,j m j n ...
最大m子段和
51nod 1052 題意描述 給定陣列a,長度為n。給定整數m,求不相交的m段字段和的最大值。當m 1 時 該問題就是最大子段和問題。設dp i 為以a i 結尾的最大子段和,當我們考慮dp i 的時候如果dp i 1 0那麼肯定把a i 接在後面最優,否則,取a i 最優。得到 dp i max...