【最大M子段和】dp + 滚动数组
题目描述
给定 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]如上所述,对于新加入的元素,有两种决策:
- 加到上一次的最后一段。
- 独立成段。
转移方程就为:$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 + 滚动数组的更多相关文章
- HDU 1024 Max Sum Plus Plus --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- POJ 3666 Making the Grade (DP滚动数组)
题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A[i],修理后是B[i],花费|A[i] – B[i]|,求最小花费.(数据有问题,代码只是单调递增的情况) #include <stdio ...
- HDU 5119 Happy Matt Friends (背包DP + 滚动数组)
题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt ...
- USACO 2009 Open Grazing2 /// DP+滚动数组oj26223
题目大意: 输入n,s:n头牛 s个栅栏 输入n头牛的初始位置 改变他们的位置,满足 1.第一头与最后一头的距离尽量大 2.相邻两头牛之间的距离尽量满足 d=(s-1)/(n-1),偏差不超过1 3. ...
- BZOJ-1925 地精部落 烧脑DP+滚动数组
1925: [Sdoi2010]地精部落 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1053 Solved: 633 [Submit][Status ...
- Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)
题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A ...
- hdu 1513 && 1159 poj Palindrome (dp, 滚动数组, LCS)
题目 以前做过的一道题, 今天又加了一种方法 整理了一下..... 题意:给出一个字符串,问要将这个字符串变成回文串要添加最少几个字符. 方法一: 将该字符串与其反转求一次LCS,然后所求就是n减去 ...
- 【BZOJ】1925: [Sdoi2010]地精部落 DP+滚动数组
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1925 题意:输入一个数N(1 <= N <= 4200),问将这些数排列成折线 ...
- tyvj P1519 博彩游戏(AC自动机+DP滚动数组)
P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...
随机推荐
- query中prop()方法和attr()方法的区别
query1.6中新加了一个方法prop(),一直没用过它,官方解释只有一句话:获取在匹配的元素集中的第一个元素的属性值. 官方例举的例子感觉和attr()差不多,也不知道有什么区别,既然有了prop ...
- echarts+百度地图+vue 填坑记(一)(百度地图、鼠标移入移出标注,信息框会产生闪烁)
大概七月底开始实习,到现在经历了两个完整的项目(c2b). 因为开发时间紧,任务重,所以在开发过程踩到的坑都没时间去记录. 现在在开发一个某链运输监控系统,到了收尾阶段,有时间写博客了!开心! 一.鼠 ...
- oracle expdp 备份脚本
#!/bin/bash#Oracle 环境变量 NLS_LANG=AMERICAN_AMERICA.AL32UTF8 ORACLE_SID=zgw ORACLE_BASE=/opt/oracle OR ...
- WSL(Windows上的Linux子系统)
WSL(Windows上的Linux子系统) WSL,Windows Subsystem for Linux,就是之前的Bash on [Ubuntu on] Windows(嗯,微软改名部KPI++ ...
- 使用wepy开发微信小程序商城第二篇:路由配置和页面结构
使用wepy开发微信小程序商城 第二篇:路由配置和页面结构 前言: 最近公司在做一个微信小程序的项目,用的是类似于vue的wepy框架.我也借此机会学习和实践一下. 小程序官方文档:https://d ...
- 一些mysql innodb的建议
http://blog.csdn.net/yunhua_lee/article/details/8239145 原文:http://dev.mysql.com/doc/refman/5.5/en/in ...
- JSP中文件的上传于下载演示样例
一.文件上传的原理 1.文件上传的前提: a.form表单的method必须是post b.form表单的enctype必须是multipart/form-da ...
- 10、V4L2摄像头获取单幅图片测试程序(MMAP模式)
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h> ...
- word中公式的排版及标题列表
1.首先建好你的标题,如标题1,标题2等等,你能够依次改变它们的字体,段落等格式,新建格式例如以下图所看到的 红圈处即建立新的格式,你能够建立不论什么你想要的格式,非常方便: 2.当你建立好了多个标题 ...
- [AngularJS] Using an AngularJS directive to hide the keyboard on submit
Pleasea refer to Link <form ng-submit="foo()" handle-phone-submit> <input type=&q ...