HDU 1024 Max Sum Plus Plus

来源:互联网 发布:农村广电网络宽带 编辑:程序博客网 时间:2024/04/28 21:06


DP问题


解题步骤已经在代码中解释的很清楚了


DP题的代码个人认为是挺难理解的,但是,如果理解了就会觉得很简单


需要注意一下的是,题目让分两段,必须就得分两段,即使分成两段之后的总和反而更小


比如代码注释中我举得例子


package 动态规划;import java.util.Scanner;public class _1024_选择多次最长子序列 {/** * m=3,n=6      | -1 | 4 | -2 | 3 | -2 |  3  | *  * now:   | 0  | -1 | 4 | 2  | 5 | 3  |  6  | *  * pre:    |-99 | -1 | 4 | 4  | 5 | 5  |  0  | *  * now:    | 0  | -1 | 3 | 2  | 7 | 5  |  8  | *  * pre:   |-99 |-99 | 3 | 3  | 7 | 7  |  0  | *  * now:    | 0  | -1 | 3 | 1  | 6 | 5  |  10 | *  * pre:    |-99 |-99 |-99| 1  | 6 | 6  |  0  | *  * @param args */// http://acm.hdu.edu.cn/showproblem.php?pid=1024// 状态: dp[i][j] --- 表示前j个数中的最大i段子段和,并且a[j]包涵于最后一个子段// 状态转移方程: dp[i][j]=max{dp[i][j-1]+A[j],dp[i-1][t]+a[j] (i-1<=t<n-m+i) }// 关于状态转移方程的解释:// dp[i][j]由两种情况得到,// 一、a[j]包涵于最后一个子段,这种情况的最大值就是EDP[i][j-1]+a[j];// 二、a[j]就是最后一个子段,这种情况的最大值是 dp[i-1][t]+a[j] (i-1<=t<=n-m+i) 中// 的最大值.// 以下用滚动数组进行DP// 在求 dp[i][j]时也顺便把 max{dp[i - 1][t]} ( i - 1 <= t < j) 求出来,这样的话// 时间复杂度仅为 O(N*(N - M + 1)) , 空间为 O( N )public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int m = sc.nextInt();int n = sc.nextInt();// 输入int[] num = new int[n + 1];// 滚动数组// now[j]代表在加上num[j]这个数之后最大可能的值,可能会更小int[] now = new int[n + 1];// pre[j]代表在num[j+1]这个数之前的最优值int[] pre = new int[n + 1];// 输入for (int i = 1; i <= n; i++) {num[i] = sc.nextInt();}// 初始化max_preint max_pre = 0;// 遍历m次for (int i = 1; i <= m; i++) {// 刚开始max_pre值为整数型最小值max_pre = -Integer.MAX_VALUE;// 遍历i→n//这里j=i的意思是,前边i个数已经没得选了,因为必定得分段,即必须得选上//注意,now[j],j=i时,这个数也是不得不选的//从j开始,也是为了让pre[j-1]是负最大值,j=i+1时用得着//表示下一个i,第i+1个数之前没得选择,它前边只能是i个值相加//之后就有一定的选择性了//比如,运行程序,测试一下://1 2 -1 4//4//2 2 -1 4//3//可见,第二次 两个都选上了,虽然结果还不如选一段for (int j = i; j <= n; j++) {//now不一定是最优的,now是在不断的尝试now或是max_pre加新的值now[j] = max(now[j - 1] + num[j], pre[j - 1] + num[j]);//每一个pre[j-1]都是对于第i次,第j个数之前最优的pre[j - 1] = max_pre;//每行的最后一个数不一定是最大的,max_pre才是if (now[j] > max_pre) {//max_pre取当前最大值max_pre = now[j];}}}System.out.println(max_pre);}}public static int max(int a, int b) {if (a > b)return a;return b;}}


原创粉丝点击