HDOJ problem1003(DP)

来源:互联网 发布:十面埋伏音乐知乎 编辑:程序博客网 时间:2024/06/11 10:23

<span style="font-size:18px;"><span style="font-family: 'Microsoft YaHei'; background-color: rgb(255, 255, 255);">方法一:非动态规</span><span style="font-family: 'Microsoft YaHei'; background-color: rgb(255, 255, 255);">划</span></span>
<span style="font-family: 'Microsoft YaHei'; background-color: rgb(255, 255, 255);"></span><pre name="code" class="java">package com.learn.bestcoder;import java.util.ArrayList;import java.util.List;import java.util.Scanner;public class Problem1003 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int count = scan.nextInt();int temp = count;List<int[]> list = new ArrayList<>();while(temp -- > 0){int length = scan.nextInt();int[] array = new int[length];for(int i = 0; i < length; i ++)array[i] = scan.nextInt();list.add(array);}for(int i = 0; i < count; i ++){maxSubSum(list.get(i), i );if(i != count - 1)System.out.println();}}public static void maxSubSum(int[] array, int index){int sum = 0;int head = 0;int temp = 0;int tail = 0;//int max = sum;int max = array[0];for(int i = 0; i < array.length; i ++){sum += array[i];if(sum > max){max = sum;tail = i;head = temp;}if(sum < 0){sum = 0;temp = i + 1;}}System.out.println("Case " + (++ index) + ":");System.out.println(max + " " + (head + 1) + " " + (tail + 1));}}

<span style="font-family: 'Microsoft YaHei'; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">方法二:动态规划</span></span>

import java.util.ArrayList;import java.util.List;import java.util.Scanner;public class Main{    public static void main(String[] args) {        Scanner scan = new Scanner(System.in);        int count = scan.nextInt();        int temp = count;        List<int[]> list = new ArrayList<>();        while(temp -- > 0){            int length = scan.nextInt();            int[] array = new int[length];            for(int i = 0; i < length; i ++)                array[i] = scan.nextInt();            list.add(array);        }                for(int i = 0; i < count; i ++){            maxSubSum(list.get(i), i );            if(i != count - 1)                System.out.println();        }    }        public static void maxSubSum(int[] array, int index){        int[] dp = new int[array.length];        int head = 0;        int tail = 0;        int max = array[0];        dp[0] = array[0];        int temp = 0;                for(int i = 1; i < array.length; i ++){            if ( dp[ i - 1 ] >= 0 ) {                dp[ i ] = dp [ i - 1 ] + array [ i ];            }            else {                dp [ i ] = array [ i ];                temp = i;            }            if ( dp [ i ] > max ) {                max = dp [ i ];                tail = i;                head = temp;            }        }                System.out.println("Case " + (++ index) + ":");        System.out.println(max + " " + (head + 1) + " " + (tail + 1));    }}

我一开始对动规方法理解错误的地方:

我搞错了父亲的结果和子序列结果的关系。我认为,可能存在一种情况,子序列0~8的最大子序列和为(2,5),这种情况下,父序列0~16的最大子序列肯定不能是包含(2,5)的,因为在(6,8)中间可能都是负数。但实际上,只要紧挨着(9,16)之前的序列的和大于0,就可以包含这个序列的。所以正确的父子关系是:

if ( dp[ i - 1 ] > 0 ) {

dp[ i ] = dp [ i - 1 ] + array [ i ];

}

else {

dp [ i ] = array [ i ];

temp = i;

}

if ( dp [ i ] > max ) {

max = dp [ i ];

tail = i;

head = temp;

}

0 0
原创粉丝点击