您的位置:首页 > 其它

最大子序列和:一道题窥探分治与动态规划

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: