HDU 2746 ——Max Sum Plus Plus Plus

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1244

Problem Description

给定一个由n个正整数组成的整数序列

a1 a2 a3 ... an

求按先后次序在其中取m段长度分别为l1、l2、l3...lm的不交叠的连续整数的和的最大值。

Input

第一行是一个整数n(0 ≤ n ≤ 1000),n = 0表示输入结束
第二行的第一个数是m(1 ≤ m ≤ 20),
第二行接下来有m个整数l1,l2...lm。
第三行是n个整数a1, a2, a2 ... an.

Output

输出m段整数和的最大值。

Sample Input

3
2 1 1
1 2 3
4
2 1 2
1 2 3 5
0

Sample Output

5 10

DFS + 记忆化

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#define INF 0x3f3f3f3f
using namespace std;

int a[1005];
int sum[1005];
int l[25];
int dp[25][1005];
int n, m;

int dfs(int i, int cur)
{
    if(cur > n)    return -INF;

    if(i==m+1)    return 0;

    if(dp[i][cur])    return dp[i][cur];

    int ret=-INF;
    for(int k=cur; k<n; k++) {
        ret = max(ret, dfs(i+1, k+l[i])+sum[k+l[i]]-sum[k]);
    }
    return dp[i][cur] = ret;
}

int main ()
{
    while(scanf("%d", &n) != EOF && n) {
        scanf("%d", &m);
        for(int i=1; i<=m; i++) {
            scanf("%d", &l[i]);
        }
        for(int i=1; i<=n; i++) {
            scanf("%d", &a[i]);
            sum[i] = sum[i-1] + a[i];
        }
        printf("%d\n", dfs(1, 0));
        memset(dp, 0, sizeof(dp));
    }

    return 0;
}
时间: 2024-08-10 02:02:39

HDU 2746 ——Max Sum Plus Plus Plus的相关文章

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]直接接在前面

[2016-03-28][HDU][1024][Max Sum Plus Plus]

时间:2016-03-28 17:45:33 星期一 题目编号:[2016-03-28][HDU][1024][Max Sum Plus Plus] 题目大意:从n个数字提取出一定数字组成m个部分,使得这个部分的总和最大 分析: dp[i][j]表示前i段计算第j个数字,dp[i][j] = max(dp[i - 1][j - 1] + a[j],dp[i][k] + a[j]); #include <algorithm> #include <cstring> #include &

HDU 3415 Max Sum of Max-K-sub-sequence 单调队列题解

本题又是一题单调队列题解. 技巧就是需要计算好前n项和Sn = a1 + a2 + ... an 这样方便处理. 记录一条单调队列,其意义是: q(head), q(head+1), ...q(tail) 其中头q(head)代表当前最佳解的起点 这样我们只需要在求某点为结尾的S[i] - S[q(head)就得到当前最佳值. 了解了单调数列,知道其中的记录意义,那么这道题就没有难度了.我也是了解这些信息之后就自己敲出代码的. 不过有些细节没写好也让我WA了几次. 最近少刷水题,而一直都是每天一

hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)

题目链接:hdu 3415 Max Sum of Max-K-sub-sequence 题意: 给你一串形成环的数,让你找一段长度不大于k的子段使得和最大. 题解: 我们先把头和尾拼起来,令前i个数的和为sum[i]. 然后问题变成了求一个max{sum[i]-sum[j]}(i-k<j<i) 意思就是对于每一个sum[i],我们只需要找一个满足条件的最小的sum[j],然后我们就可以用一个单调队列来维护. 1 #include<bits/stdc++.h> 2 #define F

Hdu 1024 Max Sum Plus Plus (dp)

题目链接: Hdu 1024 Max Sum Plus Plus 题目描述: 给出n个数,问m段连续子序列的和相加最大是多少? 解题思路: dp[i][j]表示把前i个元素(包括第i个),分成j段的最大和.状态转移方程就是dp[i][j] = max (dp[i-1][j] + arr[j],  max( dp[k][j-1]) + arr[j]),其中0<k<i.(第i个元素是保存在第j段,还是自己单独成段) 由于1<=n<=1000,000.n*n的数组肯定会爆炸,所以要对方程

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 1244 Max Sum Plus Plus Plus

虽然这道题看起来和 HDU 1024  Max Sum Plus Plus 看起来很像,可是感觉这道题比1024要简单一些 前面WA了几次,因为我开始把dp[22][maxn]写成dp[maxn][22]了,Orz 看来数组越界不一定会导致程序崩溃,也有可能返回一个错误的结果 dp[i][j]表示前j个数构成前i段所得到的最大值 状态转移方程: dp[i][j] = max{dp[i][j-1],  dp[i-1][j-len[i]] + sum[j] - sum[j-len[i]]} 分别对应

HDU 3415 Max Sum of Max-K-sub-sequence

转载请注明出处:http://blog.csdn.net/u012860063 Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5791    Accepted Submission(s): 2083 Problem Description Given a circle seq

[ACM] hdu 3415 Max Sum of Max-K-sub-sequence (单调队列)

高一时,学校组织去韶山游玩,我没去,这次趁着五一,总算去了我心心念念的韶山.其实我知道所有的景点都是差不多的,可是因为电视剧<恰同学少年>,让我对毛泽东有了进一层的了解,所以,我一直都想去看看. 有两个同学一男一女是我理想的旅友,可是女生不想去,而男士回家了.所以,我独自一人去了. 准备工作:一小包饼干,一小包山楂片,两个苹果,一瓶水,帽子(防晒),墨镜(装酷) 早晨5:30起床了,洗漱完毕,吃完早餐,赶到公交车站牌那里,才6点过几分.公交车6:31才到,等了近半个小时(公交车上明明说是6:0