题目描述

给定 n 个数求这 n 个数划分成互不相交的 m 段的最大 m 子段和。

给出一段整数序列 A1,A2,A3,A4,...,Ax,...,An ,其中 1≤x≤n≤1,000,000, -32768≤Sx≤32767。

我们定义一种函数 sum(i,j)=Ai + ... + Aj (1≤i≤j≤n,且Ai~Aj 是连续的数)。

现在,我们得到一个正整数 m(1≤x≤m≤30),你的工作是寻找 m 对 i 与 j。这 m 对 i 和 j 满足以下条件:
  sum(i1,j1)+sum(i2,j2)+sum(i3,j3)+...+sum(im,jm)在这个序列中最大。
注意:任意两区间[ix,jx]和[iy,jy]的交集均为空集。

请你求出:最大的 sum(i1,j1)+sum(i2,j2)+sum(i3,j3)+...+sum(im,jm)是多少?

输入格式

第一行两个整数 n,m 。
第二行由空格隔开的 n 个整数,即 A1~An 。

输出格式

请输出我们定义的:sum(i1,j1)+sum(i2,j2)+sum(i3,j3)+...+sum(im,jm)的最大值,即最大的 m 子段和。

样例数据 1

输入

3 1 
1 2 3

输出

6

样例数据 2

输入

6 2 
-1 4 -2 3 -2 3

输出

8

题目分析

形如“求将x,分成y份的最*值”问题,通常dp都为 f[j][i],表示将前j个元素分成i份的最*值。

这道题也一样:f[j][i]如上所述,对于新加入的元素,有两种决策:

  1. 加到上一次的最后一段。
  2. 独立成段。

  转移方程就为:$f[j][i] = max(f[j - 1][i] + val[i], max_{k = 1}^{j - 1}\{f[k][i - 1]\} + val[i])$  

  稍微计算一下,会发现这样的空间已经报表。接下来就是滚动数组登场了。

  可以发现,转移方程中的j这一维总是从上一次的j-1转移,而i不变,而且f[j - 1][k]也只需要上一次的最大值即可,那么就可以使用滚动数组进行如下优化:

  1. 去掉i这一维, 并把i这一维提到外循环->保证j-1到j都是i这一维。 数组只需要f[N]

  2.用mx[j - 1]来表示$max_{k = 1}^{j - 1}\{f[k][i - 1]\} $, 每次内循环(j)更新, 以供下一个外循环(i)使用。

  于是转移变为:

for(int i = ; i <= m; i++){
ll tmp = -oo;
for(int j = i; j <= n; j++){
f[j] = max(f[j - ] + val[j], mx[j - ] + val[j]);
tmp = max(tmp, f[j - ]);
mx[j - ] = tmp;
}
}

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std; const int N = 1e6 + , oo = 0x7fffffff;
int n, m;
typedef long long ll;
ll f[N], mx[N], val[N]; inline ll read(){
ll i = , f = ; char ch = getchar();
for(; (ch < '' || ch > '') && ch != '-'; ch = getchar());
if(ch == '-') f = -, ch = getchar();
for(; ch >= '' && ch <= ''; ch = getchar())
i = (i << ) + (i << ) + (ch - '');
return i * f;
} inline void wr(ll x){
if(x < ) putchar('-'), x = -x;
if(x > ) wr(x / );
putchar(x%+'');
} int main(){
n = read(), m = read();
   memset(f, -127, sizeof f);
for(int i = ; i <= n; i++) val[i] = read();
for(int i = ; i <= m; i++){
ll tmp = -oo;
for(int j = i; j <= n; j++){
f[j] = max(f[j - ] + val[j], mx[j - ] + val[j]);
tmp = max(tmp, f[j - ]);
mx[j - ] = tmp;
}
}
ll ans = -oo;
for(int i = m; i <= n; i++)
ans = max(ans, f[i]);
wr(ans), putchar('\n');
return ;
}

【最大M子段和】dp + 滚动数组的更多相关文章

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

    HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...

  2. POJ 3666 Making the Grade (DP滚动数组)

    题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A[i],修理后是B[i],花费|A[i] – B[i]|,求最小花费.(数据有问题,代码只是单调递增的情况) #include <stdio ...

  3. HDU 5119 Happy Matt Friends (背包DP + 滚动数组)

    题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt ...

  4. USACO 2009 Open Grazing2 /// DP+滚动数组oj26223

    题目大意: 输入n,s:n头牛 s个栅栏 输入n头牛的初始位置 改变他们的位置,满足 1.第一头与最后一头的距离尽量大 2.相邻两头牛之间的距离尽量满足 d=(s-1)/(n-1),偏差不超过1 3. ...

  5. BZOJ-1925 地精部落 烧脑DP+滚动数组

    1925: [Sdoi2010]地精部落 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1053 Solved: 633 [Submit][Status ...

  6. Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)

    题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A ...

  7. hdu 1513 && 1159 poj Palindrome (dp, 滚动数组, LCS)

    题目 以前做过的一道题, 今天又加了一种方法 整理了一下..... 题意:给出一个字符串,问要将这个字符串变成回文串要添加最少几个字符. 方法一: 将该字符串与其反转求一次LCS,然后所求就是n减去 ...

  8. 【BZOJ】1925: [Sdoi2010]地精部落 DP+滚动数组

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1925 题意:输入一个数N(1 <= N <= 4200),问将这些数排列成折线 ...

  9. tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

    P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...

随机推荐

  1. windows下安装emscripten

    windows下安装emscripten windows下安装emscripten需要python.git环境 python安装 git安装 开始安装 # 1.克隆emsdk git clone ht ...

  2. MySQL 概述和基础

    # MySQL 概述 什么是数据库 存储数据的仓库 都有哪些公司在用数据库 金融机构.游戏网站.购物网站.论坛网站-- 提供数据库服务的软件 MySQL.Oracle.SQL Server.DB2.M ...

  3. python3 用递归方法列出所有目录与文件

    python3 用递归方法列出所有目录与文件 # !/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan import os ...

  4. 读文件头数据判断 PE 文件格式和类型

    namespace X.Reflection { using System; using System.IO; public static partial class ReflectionX { pu ...

  5. Mybatis的使用中的一些不太注意的技巧

    以下就总结一下Mybatis的使用中的一些不太注意的技巧,算是Mybatis的总结笔 1.插入时主键返回 我们向数据库插入一条记录是,使用Mybatis的<insert>是无法返回插入的主 ...

  6. 视频编码器评測系统:VideoCodecRank

    视频编码器领域一直有个比較复杂的问题:mpeg2.divx.xvid.mpeg4.vp8.vp9.x264.openh264.x265等等这一系列编码器究竟哪个好?而对于同一种视频编码器,又包括了各种 ...

  7. Cocos2dx 小技巧(十六)再谈visit(getDescription)

    之前两篇都是介绍与Value相关的,这篇我继续这个话题吧,正好凑个"Value三板斧系列...".在非常久非常久曾经.我用写过一篇博客,关于怎样查看CCArray与CCDictio ...

  8. HDU 1287 破译密码 异或运算

    http://acm.hdu.edu.cn/showproblem.php?pid=1287 题目: 有个叫"猪头帮"的国家,采用一种简单的文法加密,他们所用的语言里面只有大写字母 ...

  9. MCI

    MCI(Media Control Interface)媒体控件接口是Mircrosoft提供的一组多媒体和文件的标准接口.它的好处是可以方便地控制绝大多数多媒体设备 包括音频,视频,影碟,录像等多媒 ...

  10. WIFI 状态栏显示的wifi信号强度与wifisetting列表不一致

    [DESCRIPTION] 状态栏显示的wifi信号强度与wifisetting列表不一致(不同步) [ANALYSIS] 1.apk都是接收RSSI_CHANGED intent,并调用WifiMa ...