hdoj——1003 最大子序列和

原题链接

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 an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

Output
For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.

Sample Input
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

Sample Output
Case 1:
14 1 4

Case 2:
7 1 6

Author
Ignatius.L

以前在算法书上当;例题解过,思想倒是记住了,但是实现的时候还是WA了好几次
思路:定义结构体保存区间状态max保存最优解的状态,temp为动态区间它保存从le到ri的所有数字的和,当这个和大于max状态的和时,将temp赋给max将最优解保存下来,当temp的sum小于0时,给它赋值0并将区间移到当前位置,然后继续往下走

看代码吧:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<list>
#include<iterator>
#include<stack>
#include <queue>
#include <cstdio>
//#include<algorithm>
using namespace std;
typedef  long long ll;
typedef unsigned long long ull;
#define e 2.718281828459
#define INF 0x7fffffff
#pragma warning(disable:4996)
#define sf scanf
#define pf printf
#define sf2d(x,y) scanf("%d %d",&(x),&(y))
#define sfd(x) scanf("%d",&x)
#define sff(p) scanf("%lf",&p)
#define pfd(x) printf("%d\n",x)
#define mset(x,b) memset((x),b,sizeof(x))
const double pi = acos(-1.0);
const long long mod = 1000000007LL;
int a[100002];
struct node {
    int le,ri;//区间左右端点
    ll sum;//和
    node():le(0),ri(0),sum(0){

    }
    bool operator>=(node& a) {
        return sum >= a.sum;
    }
};

int main(void){
    int t, n;
    sfd(t);
    for(int m=1; m<=t ; m++){
        node max, temp;
        sfd(n);
        for (int i = 0; i < n; i++) 
            sfd(a[i]);
        max.sum = -1001;//初始化为最小值

        for (int i = 0; i < n; i++) {
            temp.sum += a[i];//更新temp的sum
            temp.ri = i;//更新区间右端点
            if (temp >= max) {//保存最优解
                max = temp;
            }

            if (temp.sum < 0) {//当temp.max<0时说明当前这个区间绝对不会是最优解(最大子序列和肯定大于0的),此时将区间更新到以当前位置为左端点的区间状态
                temp.ri = temp.le = i+1;
                temp.sum = 0;
            }
        }

        pf("Case %d:\n", m);
        //注意下打印的格式
        if (m < t) 
            pf("%lld %d %d\n\n", max.sum,max.le+1, max.ri+1);
        else
            pf("%lld %d %d\n", max.sum, max.le + 1, max.ri + 1);

    }

    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值