最大子段和问题(C/C++)
2024-09-01 14:11:51
Description
给定有n个整数(可能为负整数)组成的序列a1,a2,...,an,求该序列连续的子段和的最大值。 如果该子段的所有元素和是负整数时定义其最大子段和为0。
Input
第一行有一个正整数n(n<1000),后面跟n个整数,绝对值都小于10000。直到文件结束。
Output
输出它的最大子段和。
Sample Input
6 -2 11 -4 13 -5 -2
Sample Output
20
参考: https://blog.csdn.net/niteip/article/details/7444973#
穷举法 时间复杂度:$O(n^3)$
/*O(n^3)*/
#include <stdio.h>
#include <stdlib.h> int main()
{
int n;
int num[1001];
int i, j, k;
int sum, max;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i++)
scanf("%d", &num[i]);
max = 0;
for (i = 0; i < n; i++)
{
for (j = i; j < n; j++)
{
sum = 0;
for (k = i; k <= j; k++)
sum += num[k];
if (sum > max)
max = sum;
}
}
printf("%d\n", max);
}
return 0;
}
穷举法
时间复杂度:$O(n^2)$
/*O(n^2)*/
#include <stdio.h>
#include <stdlib.h> int main()
{
int n;
int num[1001];
int i, j, k;
int sum, max;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i++)
scanf("%d", &num[i]);
max = 0;
for (i = 0; i < n; i++)
{
sum = 0;
for (j = i; j < n; j++)
{
sum += num[j];
if (sum > max)
max = sum;
}
}
printf("%d\n", max);
}
return 0;
}
分治法
时间复杂度:$O(nlog_2n)$
/*O(nlogn)分治法*/
#include <iostream>
#include <cstdio>
#include <cstdlib> int maxSubSegSum(int num[], int left, int right)
{
int mid = (left + right) / 2; if (left == right)
return num[left] > 0 ? num[left] : 0; int leftMaxSum = maxSubSegSum(num, left, mid);
int rightMaxSum = maxSubSegSum(num, mid + 1, right); int sum = 0;
int leftSum = 0;
for (int i = mid; i >= left; i--)
{
sum += num[i];
if (sum > leftSum)
leftSum = sum;
} sum = 0;
int rightSum = 0;
for (int i = mid + 1; i <= right; i++)
{
sum += num[i];
if (sum > rightSum)
rightSum = sum;
} int retSum = leftSum + rightSum;
if (retSum < leftMaxSum)
retSum = leftMaxSum;
if (retSum < rightMaxSum)
retSum = rightMaxSum;
return retSum;
} int main()
{
int n;
int num[1001]; while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
scanf("%d", &num[i]);
printf("%d\n", maxSubSegSum(num, 0, n - 1));
}
return 0;
}
动态规划
时间复杂度:$O(n)$
/*O(n) 动态规划*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h> int main()
{
int n;
int num[1001];
int f[1001 + 1];
int i;
int max;
while (~scanf("%d", &n))
{
for (i = 1; i <= n; i++)
scanf("%d", &num[i]);
max = 0;
memset(f, 0, sizeof(f));
for (i = 1; i <= n; i++)
{
if (f[i - 1] > 0)
f[i] = f[i - 1] + num[i];
else
f[i] = num[i];
if (f[i] > max)
max = f[i];
}
printf("%d\n", max);
}
return 0;
}
或者
/*O(n) 动态规划*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h> int main()
{
int n;
int num[1001];
int b;
int i;
int max;
while (~scanf("%d", &n))
{
for (i = 1; i <= n; i++)
scanf("%d", &num[i]);
max = 0;
b = 0;
for (i = 1; i <= n; i++)
{
b = b > 0 ? b + num[i] : num[i];
max = b > max ? b : max;
}
printf("%d\n", max);
}
return 0;
}
最新文章
- maven archetype二三事
- 提交本地项目到github服务器
- IOS开发之——CocoaPods安装和使用 OC和swift通吃
- fzuoj Problem 2177 ytaaa
- hdu 1863 畅通工程(最小生成树,基础)
- N!末尾有多少个零
- Qt入门(19)——自定义窗口部件
- javascript string对象的属性与方法
- 定制ToolChain for ARM
- OKR 方法 学习笔记
- UVA 718 - Skyscraper Floors(数论)
- ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
- Apache Tomcat部署java web项目
- python爬虫下载文件
- Java 中的String、StringBuilder与StringBuffer的区别联系(转载)
- 更新pip和setuptools
- Python爬虫项目--爬取某宝男装信息
- start-stop-daemon 启动停止系统守护进程
- Word 2010 制作文档结构之章节自动编号
- DBLookupComboBox 的初始值
热门文章
- Spring源码解析之基础应用(三)
- Helium文档11-WebUI自动化-attach_file上传文件或图片
- .net core2.2 HealthChecks记录
- linux环境下protobuf安装
- 性能测试之JVM的故障排查-死锁
- SSM中 web.xml配置文件
- Mybatis初学经验----------------(2)
- Docker学习笔记之--.Net Core项目容器连接mssql容器(环境:centos7)
- ceph踩坑日记之rgw_dynamic_resharding
- P5530 [BOI 2002]双调路径