最大子段和问题(C/C++)
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;
}
最大子段和问题(C/C++)的更多相关文章
- 最大子段和(c++)
// 最大子段和.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using namesp ...
- 51Node 1065----最小正子段和
51Node 1065----最小正子段和 N个整数组成的序列a[1],a[2],a[3],…,a[n],从中选出一个子序列(a[i],a[i+1],…a[j]),使这个子序列的和>0,并且这 ...
- 最大M子段和 V2
51nod1053 这题还是我们熟悉的M子段和,只不过N,M<=50000. 这题似乎是一个堆+链表的题目啊 开始考虑把所有正数负数锁在一起. 比如: 1 2 3 -1 –2 -3 666 缩成 ...
- 51nod 循环数组最大子段和
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 对于普通的数组,只要求一次最大子段和即可.但是这题是可以循环的,所 ...
- [日常训练]最大M子段和
Description 在长度为的序列中选出段互不相交的子段,求最大字段和. Input 第一行两个整数. 第二行个整数. Output 一行一个整数表示最大值. Sample Input 5 2 1 ...
- 51nod1049(计算最大子段和)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049 题意:又是仲文题诶- 思路:暴力会超时,又好像没什么专门 ...
- XCOJ 1103 (LCA+树链最大子段和)
题目链接: http://xcacm.hfut.edu.cn/problem.php?id=1103 题目大意:链更新.链查询,求树链的最大子段和.(子段可以为空) 解题思路: 将所有Query离线存 ...
- 洛谷P1121 环状最大两段子段和
题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的第一行是一个正整数N,表示了序列 ...
- [51NOD1959]循环数组最大子段和(dp,思路)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 这道题的最大子段和有两种可能,一种是常规的子段和,另一种 ...
- 转载:最大子段和问题(Maximum Interval Sum)
一.问题描述 给定长度为n的整数序列,a[1...n], 求[1,n]某个子区间[i , j]使得a[i]+…+a[j]和最大.或者求出最大的这个和. 例如(-2,11,- ...
随机推荐
- linux(centos8):安装prometheus服务端/node_exporter客户端(prometheus 2.18.1)
一,prometheus的用途 Prometheus是一个开源的系统监控和警报工具包 相比其他监控系统,它更适用于微服务的体系架构 它使用各种专用exporter,用来实现对硬件/存储/数据库/web ...
- 源码安装中./configure的使用
在linux中安装源码,在源码目录下使用 ./configure --prefix=xxx --with=xxx 其中configure是一个可执行脚本, --prefix 选项就是配置安装的路径, ...
- ORA-28000错误解决方案
当使用SQL*Plus登录时,Oracle数据库时提示"ORA-28000:帐号被锁定". 导致出现改错误的原因是:在oracle database 11g中,默认在default ...
- 19. [链表][双指针]删除链表的倒数第N个节点
19. 删除链表的倒数第N个节点 方法一:哨兵节点+快慢指针 在本题中,快慢指针的用法为:让快指针先走几步,步数由 \(n\) 决定. 使用哨兵节点的理由是为了避免删除节点为头结点引发的空指针异常. ...
- vue学习第一部
目录 基础操作 vue基础使用 步骤 vue的框架思想(mvvm) 显示数据 vue 常用指令 属性操作 事件绑定 操作样式 条件渲染指令 列表渲染指令 vue对象提供的属性功能 过滤器 计算和侦听属 ...
- OAuth2 快速入门
1 OAuth简述 OAuth 2.0 是一个授权协议,它允许软件应用代表(而不是充当)资源拥有者去访问资源拥有者的资源.应用向资源拥有者请求授权,然后取得令牌(token),并用它来访问资源,并且资 ...
- 专题一:why redis ?
一.NoSQL 现在互联网应用其中有两个特点:(1)海量用户(2)不可避免地高并发.常常因为这样,我们网站或者服务器将面临崩溃的风险.而多用户.高并发只是现象,究其根源,罪魁祸首就是关系型数据库, ...
- NB-IoT的eDRX模式主要目的是什么
传统的2.56秒寻呼间隔对UE的电量消耗较大,NB-IoT的eDRX模式主要目的就是支能够持更长周期的寻呼监听,从而达到省电的目的.而在下行数据发送频率小时,通过核心网和用户终端的协商配合,用户终端调 ...
- python解决百钱买百鸡
百钱买百鸡 关注公众号"轻松学编程"了解更多. 现有100钱,公鸡5文钱一只,母鸡3文钱一只,小鸡一文钱3只 要求:公鸡.母鸡,小鸡都要有,把100文钱花完,买的鸡的数量正好是10 ...
- python框架Django中MTV之Model(数据模型)
MTV框架之Model(数据模型) 关注公众号"轻松学编程"了解更多. 1.连接MySQL数据库 项目中的settings.py设置范例 # 配置数据库 DATABASES = { ...