动态规划 最大子段和
作者:互联网
代码来源于《计算机算法设计与分析》-王晓东,我只是整理一下代码笔记方便复习
<1> 蛮力法
代码;
/******************************************
* @Author : 鱼香肉丝没有鱼
* @Date : 2021-09-20 12:55:54
* @LastEditors : 鱼香肉丝没有鱼
* @LastEditTime : 2021-11-24 01:29:41
******************************************/
// 矩阵连乘
#include <iostream>
#include <stdio.h>
using namespace std;
// 蛮力法遍历每一种组合
int MaxSum(int n, int* a, int& besti, int& bestj)
{
int sum = 0;
for(int i = 1; i <= n; i++) {
for(int j = i; j <= n; j++) {
int thissum = 0;
for(int k = i; k <= j; k++) {
thissum += a[k];
}
if(thissum > sum) {
sum = thissum;
besti = i;
bestj = j;
}
}
}
return sum;
}
int main()
{
int maxsum = 0;
int besti = -1;
int bestj = -1;
freopen("file out.txt", "r", stdin);
int n; //矩阵个数
cin >> n;
int* a = NULL;
a = new int[n + 1];
for(register int i = 1; i <= n; i++) // arr的0号位不使用
cin >> a[i];
maxsum = MaxSum(n, a, besti, bestj);
cout << "最大子段和为:" << maxsum << endl;
return 0;
}
// 6
// -2 11 -4 13 -5 -2
时间复杂度 O(n3)
改进:
去掉其中一个循环
/******************************************
* @Author : 鱼香肉丝没有鱼
* @Date : 2021-09-20 12:55:54
* @LastEditors : 鱼香肉丝没有鱼
* @LastEditTime : 2021-11-24 01:29:41
******************************************/
// 矩阵连乘
#include <iostream>
#include <stdio.h>
using namespace std;
// 蛮力法遍历每一种组合
int MaxSum(int n, int* a, int& besti, int& bestj)
{
int sum = 0;
for(int i = 1; i <= n; i++) {
int thissum = 0;
for(int j = i; j <= n; j++) {
thissum += a[j];
if(thissum > sum) {
sum = thissum;
besti = i;
bestj = j;
}
}
}
return sum;
}
int main()
{
int maxsum = 0;
int besti = -1;
int bestj = -1;
freopen("file out.txt", "r", stdin);
int n; //矩阵个数
cin >> n;
int* a = NULL;
a = new int[n + 1];
for(register int i = 1; i <= n; i++) // arr的0号位不使用
cin >> a[i];
maxsum = MaxSum(n, a, besti, bestj);
cout << "最大子段和为:" << maxsum << endl;
return 0;
}
// 6
// -2 11 -4 13 -5 -2
时间复杂度 :O(n2)
<2> 分治法
基本思想:
代码:
/******************************************
* @Author : 鱼香肉丝没有鱼
* @Date : 2021-09-20 12:55:54
* @LastEditors : 鱼香肉丝没有鱼
* @LastEditTime : 2021-11-24 01:29:41
******************************************/
// 矩阵连乘
#include <iostream>
#include <stdio.h>
using namespace std;
int MaxSubSum(int* a, int left, int right)
{
int sum = 0;
if(left == right) { //如果是负数的我们规定负数的和是0
sum = a[left] > 0 ? a[left] : 0;
}
else {
// 从中间分成两个子串
int center = (left + right) / 2;
int leftsum = MaxSubSum(a, left, center);
int rightsum = MaxSubSum(a, center + 1, right);
// 左边子串的和
int s1 = 0;
int lefts = 0;
for(int i = center; i >= left; i--) {
lefts += a[i];
if(lefts > s1)
s1 = lefts;
}
// 右边子串的和
int s2 = 0;
int rights = 0;
for(int i = center + 1; i <= right; i++) {
rights += a[i];
if(rights > s2)
s2 = rights;
}
// 左右两个子串的和的和
sum = s1 + s2;
if(sum < leftsum) //取最大的
sum = leftsum;
if(sum < rightsum)
sum = rightsum;
}
return sum;
}
int MaxSum(int n, int* a)
{
return MaxSubSum(a, 1, n);
}
int main()
{
int maxsum = 0;
freopen("file out.txt", "r", stdin);
int n; //矩阵个数
cin >> n;
int* a = NULL;
a = new int[n + 1];
for(register int i = 1; i <= n; i++) // arr的0号位不使用
cin >> a[i];
maxsum = MaxSum(n, a);
cout << "最大子段和为:" << maxsum << endl;
return 0;
}
// 6
// -2 11 -4 13 -5 -2
时间复杂度: O(nlogn)
<3> 动态规划
代码:
/******************************************
* @Author : 鱼香肉丝没有鱼
* @Date : 2021-09-20 12:55:54
* @LastEditors : 鱼香肉丝没有鱼
* @LastEditTime : 2021-11-24 01:29:41
******************************************/
// 矩阵连乘
#include <iostream>
#include <stdio.h>
using namespace std;
int MaxSum(int n, int* a)
{
int sum = 0;
int b = 0;
for(int i = 1; i <= n; i++) {
if(b > 0)
b += a[i];
else
b = a[i];
if(b > sum)
sum = b;
}
return sum;
}
int main()
{
int maxsum = 0;
freopen("file out.txt", "r", stdin);
int n; //矩阵个数
cin >> n;
int* a = NULL;
a = new int[n + 1];
for(register int i = 1; i <= n; i++) // arr的0号位不使用
cin >> a[i];
maxsum = MaxSum(n, a);
cout << "最大子段和为:" << maxsum << endl;
return 0;
}
// 6
// -2 11 -4 13 -5 -2
标签:bestj,besti,include,子段,int,sum,鱼香肉丝,动态,规划 来源: https://blog.csdn.net/qq_41680771/article/details/121690675