hdu 1231&1003 -最大连续子序列-动态规划

//
//  main.cpp
//  hdu -1231 -最大连续子序列-动态规划
//
//  Created by XD on 15/9/25.
//  Copyright © 2015年 XD. All rights reserved.
//

/*
 设dp[i] 表示以位置i为起点的最大和。
 则有    dp[i] = dp[i+1] + v[i]    (dp[i+1] >= 0 )
        dp[i]  = v[i] ; (dp[i+1] <  0 )
 
 注意此题要求的是最小的位置
 所以我们要逆序求dp,然后正序遍历dp数组。这样第一个位置i就是要求的结果开始位置。
 */
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
#define ll long long
using namespace std ;
const int maxn = 10000 + 10 ;

ll a[maxn] ;
ll dp[maxn] ;
int main(int argc, const char * argv[]) {
    int k  ;
    while (scanf("%d" , &k) , k ) {
        ll l,r,mx ,temp,flag = 0 ;
        memset(dp, 0, sizeof(dp)) ;
        for (int i = 0; i < k  ; i++) {
            scanf("%lld" ,&a[i]) ;
            if (a[i] >= 0 ) {
                flag  =1 ;
            }
        }
        if (flag == 0 ) {
            printf("0 %lld %lld\n" , a[0],a[k-1]) ;
            continue ;
        }
        dp[k-1] = a[k-1] ;
        mx = a[k-1] ;
        for (int i = k-2; i >-1 ; i--) {
            if(dp[i+1] < 0 )
            {
                dp[i]  =a[i] ;
              
            }else if (dp[i+1] >= 0 )
            {
                dp[i] += (dp[i+1] + a[i]) ;
            }
            mx = mx > dp[i] ? mx: dp[i] ;
        }
        for (int i = 0; i <k; i++) {
            if (dp[i] == mx) {
                l = a[i] ;
                temp = 0 ;
                flag = 0 ;
                while (i < k&&  temp <mx ) {
                    flag =1 ;
                    temp += a[i] ;
                    i++ ;
                }
                if (i == k ) {
                    r =a[k-1] ;
                    break ;
                }
                else{
                    r = a[i-flag] ;
                    break ;
                }
            }
        }
        printf("%lld %lld %lld\n" , mx , l ,r) ;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值