最大子序列和:一道题窥探分治与动态规划
2014-04-10 15:51
309 查看
最大子序列和,这是个再经典不过的题目了,而且这一道题可以分别用分治法,动态规划来做(时间复杂度分别为O(n*lg(n))和O(n))。题目就不再赘述了,直接上代码:
首先是分治法:
动态规划:
首先是分治法:
#include <iostream> #include <limits> using namespace std; struct Tag { Tag(int _lowmark, int _highmark, int _sum) { lowmark = _lowmark; highmark = _highmark; sum = _sum; } int lowmark; int highmark; int sum; }; Tag find_maximum_cross_subarr(int a[], int p, int q, int r) { int lowmark; int lowmax = numeric_limits<int>::min(); int sum = 0; for (int i = q - 1; i >= p; i--) { sum += a[i]; if (sum > lowmax) { lowmark = i; lowmax = sum; } } int highmark; int highmax = numeric_limits<int>::min(); sum = 0; for (int i = q; i < r; i++) { sum += a[i]; if (sum > highmax) { highmark = i; highmax = sum; } } return Tag(lowmark, highmark + 1, lowmax + highmax); } Tag find_maximum_subarr(int a[], int p, int r) { if (r - p == 1) return Tag(p, r, a[p]); int q = (p + r) / 2; Tag tagleft = find_maximum_subarr(a, p, q); Tag tagright = find_maximum_subarr(a, q, r); Tag tagcross = find_maximum_cross_subarr(a, p, q, r); if (tagleft.sum > tagright.sum && tagleft.sum > tagcross.sum) return tagleft; else if (tagright.sum > tagleft.sum && tagright.sum > tagcross.sum) return tagright; else return tagcross; } int main(int argc, char** argv) { int a[] = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 }; Tag t = find_maximum_subarr(a, 0, 16); cout << t.sum << t.lowmark << t.highmark << endl; return 0; }
动态规划:
#include <iostream> #include <limits> using namespace std; struct Tag { Tag(int _l, int _r, int _sum) { l = _l; r = _r; sum = _sum; } int l; int r; int sum; }; Tag find_maximum_subarr(int a[], int n) { int maxsum = numeric_limits<int>::min(); int maxlindex = 0; int maxrindex = 0; int sum = 0; int lindex = 0; for (int i = 0; i < n; i++) { if (sum < 0) { sum = a[i]; lindex = i; } else { sum += a[i]; } if (sum > maxsum) { maxlindex = lindex; maxrindex = i + 1; maxsum = sum; } } return Tag(maxlindex, maxrindex, maxsum); } int main(int argc, char** argv) { int a[] = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 }; Tag t = find_maximum_subarr(a, 16); cout << t.sum << "," << t.l << "," << t.r << endl; return 0; }
相关文章推荐
- 蓝桥杯C语言培训6 分治法与动态规划 最大连续部分和
- (5)最大m段子序列和问题____动态规划
- SDUT_最大上升子序列的和_动态规划
- 动态规划6_最大连续子序列和
- hdu 1003 Max Sum(最大连续子序列和) (学了一下分治)
- 最大上升子序列(动态规划)
- 九度-1011 最大连续子序列(动态规划)
- 最大子段和——分治与动态规划
- Maximum Subarray 动态规划 最大连续子序列和
- 合唱队----动态规划(求解最大递增/减子序列)
- 算法导论-分治、最大子序列问题
- 最大子序列和(枚举,分治,DP)
- 动态规划实现最大连续子序列和,最长不下降子序列和最长公共子序列
- 动态规划——求连续和为最大的子序列
- 《算法导论》读书笔记(三)——分治策略之和最大连续子序列
- 动态规划回顾(1):最大连续子序列和
- 动态规划 - 最大连续子序列
- 算法导论-分治、最大子序列问题
- 数字序列加入+,*运算符后取得最大值问题; 动态规划;打破传统从决策入手思想;找出问题的特有性质;从例子入手找特点;
- hdu-1003-动态规划-求连续子序列最大和问题