Hdoj 1024 Max Sum Plus Plus 【DP】

Max Sum Plus Plus

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 18861 Accepted Submission(s): 6205

Problem Description

Now I think you have got an AC in Ignatius.L’s “Max Sum” problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

Given a consecutive number sequence S1, S2, S3, S4 … Sx, … Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + … + Sj (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + … + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

But I`m lazy, I don’t want to write a special-judge module, so you don’t have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^

Input

Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 … Sn.

Process to the end of file.

Output

Output the maximal summation described above in one line.

Sample Input

1 3 1 2 3

2 6 -1 4 -2 3 -2 3

Sample Output

6

8

Hint

Huge input, scanf and dynamic programming is recommended.

Author

JGShining(极光炫影)

题意:求在给出的n个数中找出m个连续的子序列,使得各子序列之和最大。

解题链接

代码(不是太懂,什么时候懂了再来补一个详细解释吧):

#include <cstdio>
#include <iostream>
#include <cstring>
const int M = 1e6+5;
#define LL __int64
using namespace std;

LL pre[M], num[M];

inline LL max(LL A, LL B){
    return A > B? A:B;
}

void DP(int m, int n){
    LL temp; //temp就是DP[I][J]
    for(int i = 1; i <= m; ++ i){
        temp = 0;
        for(int j = 1; j <= i; ++ j) temp += num[j];
        pre[n] = temp;
        for(int j = i+1; j <= n; ++ j){
            temp = max(temp, pre[j-1])+num[j]; //pre[j-1]就是max(dp[i-1][t])(i-1 <= t <= i-1);
            pre[j-1] = pre[n];
            pre[n] = max(temp, pre[n]);
        }
    }
}

int main(){
    int n, m;
    while(scanf("%d%d", &m, &n) == 2){
        for(int i = 1; i <= n; ++ i){
            scanf("%I64d", num+i); pre[i] = 0;
        }
        DP(m, n);
        printf("%I64d\n", pre[n]);
    }
    return 0;
} 
时间: 2024-12-22 12:22:57

Hdoj 1024 Max Sum Plus Plus 【DP】的相关文章

hdu 1024 MAX Sum Plus Plus【dp】

hdu 1024 题意:给定序列,求找出m个子序列的和使它们最大,子序列无交叉. 题解:又是最大子序列和增强版.但是这回让找m个,我还是没有思路.网上看到的思路无一例外都是: dp[i][j]表示前j个数分成i个子序列能获得的最大值.它有两大部分转移过来,一个是j是第i个序列的首元素,则dp[i][j]由dp[i-1][t]转移过来,即前t个数分成i-1个子序列:另一种自然就是第j个数不是第i个子序列的首元素,所以由前j-1个数分成i个子序列的状态dp[i][j-1]转移过来.但是数据很大,二维

HDU1024 Max Sum Plus Plus 【DP】

Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17164    Accepted Submission(s): 5651 Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem

hdu 1024 Max Sum Plus Plus(DP)

转移方程dp[i][j]=Max(dp[i][j-1]+a[j],max(dp[i-1][k] ) + a[j] ) 0<k<j 此链接中有详解点击打开链接 #include<stdio.h> #include<algorithm> #include<iostream> using namespace std; #define MAXN 1000000 #define INF 0x7fffffff int dp[MAXN+10]; int mmax[MAXN

HDU 1024 Max Sum Plus Plus【动态规划求最大M子段和详解 】

Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 29942    Accepted Submission(s): 10516 Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem

!HDU 1024 Max Sum Plus Plus-dp-(分组dp?最大分段子序列和)

题意:n个数,分成m段,求这m段的最大和,段之间不能交叉. 分析: 这题跟最大子序列和的区别在于要求分成m段,所以做法就千差万别了.实际的做法倒有点像分组dp(将n个数分成m组),但是本题与上次写的两道分组dp(搬寝室和特殊的筷子)的不同是:上两题每组选两or三个元素,本题不确定每一段要选多少个元素:上两题先排序再做,这题只能根据序列原定顺序走. 本题难点: 1.状态:dp[i][j]在确定选第j个元素的前提下,前j个分i段的最大和:所有对于j号元素有两种情况:1).加入已经确定的i段中最后一段

hdu1003 1024 Max Sum&amp;Max Sum Plus Plus【基础dp】

dp是竞赛中常见的问题,也是我的弱项orz,更要多加练习.看到邝巨巨的dp专题练习第一道是Max Sum Plus Plus,所以我顺便把之前做过的hdu1003 Max Sum拿出来又做了一遍 HDU 1003 Max Sum 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 题目描述:给一个整数序列,求其中的一段连续子序列,使它的和最大值以及这个序列的起始下标 思路:简单的dp,抓住“连续”来入手.构造pair<int,int> dp[

HDU 1024 Max Sum Plus Plus --- dp+滚动数组

HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值,其中第i个子序列包括a[j], 则max(dp[m][k]),m<=k<=n 即为所求的结果 <2>初始状态: dp[i][0] = 0, dp[0][j] = 0; <3>状态转移: 决策:a[j]自己成为一个子段,还是接在前面一个子段的后面 方程: a[j]直接接在前面

hdoj 1003 Max Sum 【最大子段和】【贪心】

题意:... 策略:看着像贪心,感觉也是贪心. 很久之前做的,又做了一遍,好题. 代码: #include<stdio.h> #include<string.h> int s[100005]; int main() { int t, i, j, l, st, en, n, v = 1; scanf("%d", &t); while(t --){ scanf("%d", &n); for(i = 1; i <= n; i

HDU 1024:Max Sum Plus Plus(DP)

http://acm.hdu.edu.cn/showproblem.php?pid=1024 Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 24675    Accepted Submission(s): 8478 Problem Description Now I think you have g