ACM 动态规划 最大 m 子段和问题(课上)

Max Sum Plus Plus

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 23976 Accepted Submission(s):
8199

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

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
const int MAX = 1e6 + 10;
const int MIN = -1e8;

int curr[MAX], pre[MAX], a[MAX];
int max_sum, n, m;

int main()
{
    while(cin >> m >> n)
    {
        for(int i = 1; i <= n; i++)
            cin >> a[i];
        memset(curr,0,sizeof(curr));
        memset(pre,0,sizeof(pre));
        int j = 0;
        for(int i = 1; i <= m; i++)
        {
            max_sum = MIN;
            for(j = i; j <= n; j++)
            {

                curr[j] = max(curr[j - 1], pre[j - 1]) + a[j];
/*
    pre[j-1]表示的是上一个状态中i...j-1的最大值,
    max_sum更新之后表示的i...j的最大值,所以不能写反了
*/
                pre[j - 1] = max_sum;
                max_sum = max(max_sum, curr[j]);
            }
            //pre[j-1]中始终保持着前一个状态的最大值,这个很重要
            pre[j - 1] = max_sum;
        }
        cout << max_sum << endl;
    }
    return 0;
}
时间: 2024-08-02 11:48:31

ACM 动态规划 最大 m 子段和问题(课上)的相关文章

ACM 动态规划 最长上升子序列(课上)

输入数据 输入的第一行是序列的长度N (1 <= N <= 1000).第二行给出序列中的N 个整数,这些整数的取值范围都在0 到10000. 输出要求 最长上升子序列的长度. 输入样例 7 1 7 3 5 9 4 8 输出样例 4 /* 课上题目 最长上升子序列 */ # include <iostream> using namespace std; const int MAX = 1e5; int a[MAX + 10]; int len[MAX + 10]; int main

ACM 动态规划 最大路径得分(课上)

问题: 给定一个具有N层的数字三角形如下图,从顶至底有多条路径,每一步可沿左斜线向下或沿右斜线向下,路径所经过的数字之和为路径得分,请求出最大路径得分.        7        3 8     8 1 0   2 7 4 4   4 5 2 6 5 用到记忆化搜索的方式,可以增加效率,用递归算法太慢了... /* 课上题目 最大路径得分 */ # include <iostream> using namespace std; const int MAX = 1e4; int dp[MA

【DP专辑】ACM动态规划总结

转载请注明出处,谢谢.   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15日 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. 本人动态规划博客地址:http://blog.csdn.net/cc_again/article/category/1261899 ******************

智慧解析第03课上:战国故事 相如出世

智慧解析第03课上:战国故事 相如出世,布布扣,bubuko.com

课上练习

package 课上作业; import java.util.InputMismatchException; import java.util.Scanner; public class Test { public static void main(String[] args) { for(int m=0;;) { int judge=0; Scanner in=new Scanner(System.in); int n; System.out.println("请输入帖子的个数:")

Construct Binary Tree from Inorder and Postorder Traversal (算法课上的题)

Construct Binary Tree from Inorder and Postorder Traversal 这道题之前算法课上好像遇到过,思路也很简单的. 思路:后序序列的最后一个元素就是树根,然后在中序序列中找到这个元素(由于题目保证没有相同的元素,因此可以唯一找到),中序序列中这个元素的左边就是左子树的中序,右边就是右子树的中序,然后根据刚才中序序列中左右子树的元素个数可以在后序序列中找到左右子树的后序序列,然后递归的求解即可.(在去除了根节点之后,中序遍历和后序遍历的前N个树都是

课上1.0

课上:  课上比较差脑子一片混乱,定义了一个数组接收hello word,本来想用ASCII码值变化来实现大小写改变,结果做到一半发现程序运行有问题不能直接用, 然后就想用指针,结果没什么头绪就下课了 课下: 百度问题,百度报错意思 #include <stdio.h> #include <stdlib.h> int main(){ char str[] = "hello word"//定义一个数组放进字符串 printf("%s\n",st

课上的程序补充

#include<stdio.h> void funstr(char *p) { *p=*p-32; *(p+6)=*(p+6)-32; printf("%s\n",p); int i; for(i=0;i<12;i++) printf("%c",*(p++)); } int main() { char str[]="hello world!"; funstr(str); } Hello World! Hello World!

课上程序的补充

#include<stdio.h> #include<string.h> int main() { void funstr(char a[]); char str[]="hello world"; str[0]-=32; str[6]-=32; funstr(str); } void funstr(char a[]) { char *p; p=a; int n; n=strlen(a); while(n) { printf("%c",*p);