Max Sum(hdu-1003)

一道很有意思的dp,说它有意思是因为他的原理其实很简单,而且扫描一次就可以得到最终的答案。

如果当前这个数之前的和小于0,那么最大和就从当前的数重新开始;否则最大和就是之前的和加上当前这个数。

这样为什么是正确的呢? 我们假设当前这个数之前的连续和小于0,那么他对下面的贡献是负的,所以无论后面的数有多大,最大连续和肯定都不如舍弃前面负贡献的和大。

然后每次更新dp[i]的最大值,就相当于由枚举的连续和的终点。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int T,n,a[100005],dp[100005];
int main(){
    scanf("%d",&T);
    int kase = 0;
    while(T--){
        scanf("%d",&n);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
        }
        printf("Case %d:\n",++kase);
        int ans = -1000000000,x1,x2,l,r;
        dp[1] = a[1];
        x1 = 1; ans = dp[1];
        l=1; r=1;
        for(int i=2;i<=n;i++){
            if(dp[i-1]<0) {
                x1 = i;
                dp[i] = a[i];
            } else dp[i] = dp[i-1] + a[i];
            if(ans<dp[i]){
                ans = dp[i];
                l = x1; r = i;
            }
        }
        printf("%d %d %d\n",ans,l,r);
        if(T) printf("\n");
    }
    return 0;
}
时间: 2024-10-06 18:43:37

Max Sum(hdu-1003)的相关文章

Max Sum (hdu 1003 简单DP水过)

Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 161294    Accepted Submission(s): 37775 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max s

HDU 1003 - Max Sum(难度:*)

Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. Input The first line of the input contains

hdu1003 Max Sum(经典dp )

A - 最大子段和 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in thi

Max Sum(经典DP)

求最长总和序列,状态转移方程:dp[i] = max(dp[i-1]+a[i].a[i]) 因为可能有负数,所以要判断dp是否大于0,如果小于0则序列中断,从中断点开始 起始点可以用数组s保存,有中断点就保存,没有的话s[i]=s[i-1] 另外还有输出最后换行的问题,有时中间要换行但最后不需要换行,如果没注意可能会出现PE #include <iostream> #include <string> #include <cstring> #include <cst

HDU 1003:Max Sum(DP)

Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 142742    Accepted Submission(s): 33225 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max s

[ACM] hdu 1003 Max Sum(最大子段和模型)

Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 135262    Accepted Submission(s): 31311 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max s

BestCoder Round #29 1003 (hdu 5172) GTY&#39;s gay friends [线段树 判不同 预处理 好题]

传送门 GTY's gay friends Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 264    Accepted Submission(s): 57 Problem Description GTY has n gay friends. To manage them conveniently, every morning he o

HDU 4961(杭电多校#9 1002题)Boring Sum(瞎搞)

题目地址:HDU 4961 看来这题的测试数据是随机的.不然出了极限数据还真过不了...这题我的方法是建一个哈希结构体,记录两个变量,分别是num位置,然后是f,f==0表示这个数没出现过,f==1表示这个数出现过.然后分别从前面和后面扫一遍.每次扫的时候,对每一个出现的数都进行标记.然后对当前的数枚举该数的倍数,全部枚举完,取位置num最大的.然后找完之后,对哈希结构体进行更新.如果前面曾经出现过的话,就直接换掉,因为后面的数总比前面的更优.最后扫完两遍之后两个数组就能求出来了.计算就行了.

BestCoder Round #70 Jam&#39;s math problem(hdu 5615)

Problem Description Jam has a math problem. He just learned factorization. He is trying to factorize ax^2+bx+cax?2??+bx+c into the form of pqx^2+(qk+mp)x+km=(px+k)(qx+m)pqx?2??+(qk+mp)x+km=(px+k)(qx+m). He could only solve the problem in which p,q,m,

BestCoder Round #1 1002 项目管理 (HDU 4858)

项目管理 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 738    Accepted Submission(s): 260 Problem Description 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的!两个节点间可能有多条边,不过一条边的两端必然是不同的节点.每个节点都有一个能量值. 现在我