POJ2479:Maximum sum
来源:互联网 发布:淘宝白内障器械 编辑:程序博客网 时间:2024/06/05 04:02
总时间限制:
1000ms
内存限制:
65536kB
描述
Given a set of n integers: A={a1,a2,..., an}, we define a function d(A) as below:
t1 t2 d(A) = max{ ∑ai + ∑aj | 1 <=s1 <= t1 < s2 <= t2 <= n } i=s1 j=s2
Your task is to calculate d(A).
输入
The input consists of T(<=30) testcases. The number of test cases (T) is given in the first line of theinput. Each test case contains two lines. The first line is an integern(2<=n<=50000). The second line contains n integers: a1, a2, ..., an.(|ai| <= 10000).There is an empty line after each case.
输出
Print exactly one line for each testcase. The line should contain the integer d(A).
样例输入
1
10
1 -1 2 2 3 -3 4 -4 5 -5
样例输出
13
提示
In the sample, we choose {2,2,3,-3,4}and {5}, then we can get the answer.Huge input,scanf is recommended
题意:给定一个数组,求两个不相交的连续子序列,使得其和最大。
分析:首先,对于一个序列,要求得一个连续子序列使其和最大的话,方法是多种的,但是存在O(n)的高效算法,那就是使用尺取法的思想不断地更新连续和的最大值。
具体实现的过程是在当前的和sum大于0,那么不断地推进区间右端点,如果小于0了,证明前面的部分的最大连续子序列和已经求出来了,直接将左端点推进至当前的位置。(这个是连续最大子序列和的计算)
回到题目,我们可以枚举断点,求出每个点左右两段的连续子序列和的最大值相加并取最大值即可。那么如何求解左右两段子序列的最大值呢?很明显的dp,令dpl[i]为1到i的区间内连续子序列和的最大值,同样地,令dpr[i]为i到n的区间内连续子序列和的最大值,那么答案就是max(dpl[i]+dpr[i+1]),根据最初的分析,一次遍历的过程就可以预处理出所有的dpl[i],反着遍历一次就可以求解dpr[i]。
整个实现的过程复杂度为O(n),如果要进一步提高效率,可以从输入下手,用scanf 代替cin,实际上cin也能过,并且在求前向连续和的时候可以在输入的时候求解。
本题的亮点是两个分段求连续的子序列和,一个正序的连续的子序列和,另一个逆序的连续的子序列和,然后因为是不相交的特点,一次遍历即可。
注意在设置最小(大)值的时候尽量INT_MIN, INT_MAX(求极值问题的时候)
不要简单的去设置一个0 或者一个大的数
还要注意要引入头文件#include<limits.h>
#include<iostream>#include<cstring>#include <stdio.h>#include<limits.h> #include<memory.h>using namespace std;int a[50010];int dpl[50010],dpr[50010]; int T,n;int main(){//freopen("2.txt","r",stdin);cin >> T;while(T--){memset(a,0,sizeof(a));memset(dpl,0,sizeof(dpl));memset(dpr,0,sizeof(dpr));cin >> n;int maxS=INT_MIN,curS=0;for(int i = 0; i< n;i++){cin >> a[i] ;curS += a[i];if(curS > maxS){maxS = curS;}if(curS <0){curS= 0;}dpl[i] = maxS;}maxS=INT_MIN; curS=0;for(int i = n-1 ; i >=0; i--){curS += a[i];if(curS > maxS){maxS = curS;}if(curS <0){curS= 0;}dpr[i] = maxS;}int ans = INT_MIN;for(int i =0; i< n-1;i++){ans = max(dpl[i]+dpr[i+1],ans);}cout <<ans<<endl;}return 0; }
- POJ2479 Maximum sum
- POJ2479 Maximum sum
- poj2479 - Maximum sum
- POJ2479 Maximum sum DP
- poj2479 Maximum sum
- poj2479 Maximum sum
- poj2479 Maximum sum
- POJ2479 Maximum sum
- poj2479 c++ : Maximum sum
- Poj2479-Maximum sum
- POJ2479&OpenJudge1481 Maximum sum
- POJ2479:Maximum sum
- Poj2593 VS Poj2479 Maximum sum
- POJ2479——Maximum sum
- POJ2479 Maximum sum 线性dp
- 【POJ2479】Maximum sum(动态规划,DP)
- POJ2479 - Maximum sum (动规)
- poj2479——Maximum sum(dp)
- 十一行Python代码实现一个误差逆传播(BP)神经网络
- Codeforces 896A
- django 用ajax+post提交form 实现前后台数据绑定
- log4j输出多个自定义日志文件
- Hello Kitty!
- POJ2479:Maximum sum
- SpringBoot小白教程 (一): 使用Maven新建SpringBoot工程
- QML Image动态刷新图片来自C++的QImage的一个巨坑
- Unable to complete the scan for annotations for web application [] due to a StackOverflowError
- samba共享存储服务
- Kotlin学习(一)
- CF895C dp/线性基
- Request和Response方法总结 - CSDN博客
- C++注释转化为C注释