HDU 1003-最大连续子序列的和-java

思路:令dp[i]表示以a[i]结尾的连续子序列的最大相加和,分析以a[i+1]结尾的连续子序列的情况:

a[i+1]结尾的连续子序列有两种可能:

    1)和以a[i]结尾的序列组成的新的序列;
    2)只包含a[i+1]

1. dp[i]<0, 且是连续的子序列,则以a[i+1]结尾的连续子序列是第二种可能情况,序列中只有a[i+1],此时dp[i+1]=a[i+1]
2. dp[i]>=0, 则以a[i+1]结尾的连续子序列是第1种情况,是a[i]结尾的序列组成的新的序列, 此时dp[i+1]=dp[i]+a[i+1];
3. 题目的要求即就是求dp[i] (其中i=0…n)的最大值

import java.util.Scanner;

public class Main {
    public static void main(String args[]) {

        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int caseNum = in.nextInt();
            for (int k = 0; k < caseNum; k++) {
                int integerNum = in.nextInt();
                int[] arr = new int[integerNum];
                int length = arr.length;
                int optSum = Integer.MIN_VALUE;
                int start = 0;
                int end = 0;
                int caseIndex = k + 1;
                int[] dp = new int[integerNum];
                for (int j = 0; j < integerNum; j++) {
                    arr[j] = in.nextInt();
                }

                dp[0] = arr[0];

                for (int i = 0; i < length - 1; i++) {
                    if (dp[i] < 0) {
                        dp[i + 1] = arr[i + 1];
                        start = i + 1;
                    } else {
                        dp[i + 1] = dp[i] + arr[i + 1];
                    }
                }
                optSum = dp[0];
                end = 0;
                for (int i = 1; i < length; i++) {

                    if (dp[i] > optSum) {
                        optSum = dp[i];
                        end = i;
                    }
                    // optSum = dp[i]>optSum?dp[i]:optSum;
                    // end = i;
                }
                int s = 0;
                start = end;
                for (int m = end; m >= 0; m--) {
                    s += arr[m];
                    if (s == optSum) {
                        start = m;
                    }
                }

                System.out.println("Case " + caseIndex + ":");
                System.out.println(optSum + " " + (start + 1) + " " + (end + 1));
                if (k < caseNum - 1) {
                    System.out.println();
                }
            }

        }

    }

}

Reference:
1. http://blog.csdn.net/ding_hai_long/article/details/20608783
2. http://blog.csdn.net/jecode/article/details/49954733

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值