HDU 1024 Max Sum Plus Plus
2013-01-05 10:24
302 查看
DP问题
解题步骤已经在代码中解释的很清楚了
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_pre int 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; } }
相关文章推荐
- HDU - 1024 Max Sum Plus Plus
- HDU 1024 Max Sum Plus Plus 简单DP
- HDOJ HDU 1024 Max Sum Plus Plus
- HDU-1024 Max Sum Plus Plus 动态规划
- hdu 1024 Max Sum Plus Plus(DP)
- hdu 1024 Max Sum Plus Plus(经典dp) 有点小bug?
- HDU 1024 Max Sum Plus Plus 经典 DP(A)
- HDU 1024 Max Sum Plus Plus(DP+滚动数组)
- HDU 1024 Max Sum Plus Plus(DP)
- HDU - 1024 Max Sum Plus Plus(dp)
- hdu 1024 Max Sum Plus Plus(dp求m个不相交子段和的最大值)
- HDU 1024 Max Sum Plus Plus
- 【HDU 1024】 Max Sum Plus Plus
- HDU 1024 Max Sum Plus Plus【DP+滚动数组】
- HDU---1024-Max Sum Plus Plus(DP)
- hdu 1024 max sum plus plus
- hdu 1024 Max Sum Plus Plus (滚动数组 &&动态规划)
- HDU 1024 Max Sum Plus Plus(DP,)
- HDU 1024 Max Sum Plus Plus
- 【HDU 1024】 Max Sum Plus Plus【动态规划求最大M子段和详解-好题 】