循环数组最大子段和 (dp)
来源:互联网 发布:java福利院管理系统 编辑:程序博客网 时间:2024/06/05 14:01
N个整数组成的循环序列a11,a22,a33,…,ann,求该序列如aii+ai+1i+1+…+ajj的连续的子段和的最大值(循环序列是指n个数围成一个圈,因此需要考虑an−1n−1,ann,a11,a22这样的序列)。当所给的整数均为负数时和为0。
例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N+1行:N个整数 (-10^9 <= Sii <= 10^9)
Output
输出循环数组的最大子段和。
Sample Input
6
-2
11
-4
13
-5
-2
Sample Output
取反也可以:
例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N+1行:N个整数 (-10^9 <= Sii <= 10^9)
Output
输出循环数组的最大子段和。
Sample Input
6
-2
11
-4
13
-5
-2
Sample Output
20
如果最大和在不循环的情况下得到,我们可以按照最大的连续子序列和的方法找到一个最大的和maxSum;如果最大和的在循环的情况下得到,我们我们可以求一个最小连续子序列的和minSum,用数组总和tot-minSum就是在循环的情况下最大和;最终答案取两者最大值ans = max{minSum,tot-maxSum}
AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <set>#include <stack>#include <queue>#include <vector>#include <cctype>using namespace std;#define CL(a) memset(a,0,sizeof(a));#define LL long longconst int INF= 0x7fffffff;const int maxn = 1e6 + 100;LL a[maxn];int main(){ int n;LL maxSum,minSum,ans,sum,tot; while (scanf("%d",&n) != EOF){ tot = 0; for (int i = 0;i < n;i++){ scanf("%lld",&a[i]); tot += a[i]; } maxSum = sum = 0; minSum = INF; for (int i = 0;i < n;i++){ sum = max(sum + a[i],0ll); maxSum = max(maxSum,sum); } for (int i = 0;i < n;i++){ sum = min(sum + a[i],0ll); minSum = min(minSum,sum); } ans = max(maxSum,tot - minSum); printf("%lld\n",ans); } return 0;}
取反也可以:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#include<queue>#include<map>#include<set>#include<vector>#include<string>#include<stack>#include<cstdlib>typedef long long ll;using namespace std;ll a[50050],dp[55000];int main(){ int n,flag=0; ll ans1=0,ans2=0,sum=0,t=0; cin>>n; int r; for(r=1;r<=n;r++){ scanf("%lld",&a[r]); t+=a[r]; if(a[r]>=0)flag=1; } if(!flag){ printf("0\n"); return 0; } else{ for(int i=1;i<=n;i++){ sum=max(sum,0ll)+a[i]; ans1=max(ans1,sum); } sum=0; for(int i=1;i<=n;i++){ a[i]=-a[i]; sum=max(sum,0ll)+a[i]; ans2=max(ans2,sum); } printf("%I64d\n",max(ans1,t+ans2)); } return 0;}
阅读全文
0 0
- DP-循环数组最大子段和
- 循环数组最大子段和 (dp)
- 51nod 循环数组最大子段和 (dp)
- 51nod 1050 循环数组最大子段和 dp
- 循环数组最大子段和(DP)
- hpu 1082: 循环数组最大子段和 [DP]
- 51nod1050 循环数组最大子段和 dp
- 51Nod 1050 循环数组最大子段和(DP—最大子段和变形)
- 51Nod-1050 循环数组最大段和【最大子段和+最小子段和+DP】
- 循环数组的最大子段和
- 循环数组的最大子段和
- 1050 循环数组最大子段和
- 1050 循环数组最大子段和
- 循环数组最大子段和
- 1050 循环数组最大子段和
- 循环数组的最大子段和
- 循环数组最大子段和
- 【hpuoj】循环数组最大子段和
- hive原理组件
- 【拜小白opencv】5-Rect类的相关操作简介
- ImageLoader github地址
- 观察者模式
- 基于 Vue 全家桶制作的移动端音乐 WebApp
- 循环数组最大子段和 (dp)
- 数字签名与数字证书技术简介(二)
- SVN初学者使用说明
- 水仙花
- iOS 偏好设置NSUserDefaults
- EasyDSS开放平台文档设计
- Opencv Mat 类详解以及像素点基本读取方法
- Tensorlayer 安装更新
- HDU 6103 Kirinriki (字符串翻转 尺取法 17多校第六场)