【书上讲解】最大m段子段和问题
描述
【题解】
设f[i][j]表示前i个数字分成了j段的最大子段和。
则f[i][j] = max(f[i-1][j]+a[i] (第i个数字和第j段合在一起),f[k][j-1]+a[i] (第i个数字作为第j段的第一个数字,同时在j-1段的情况中找到和最大的那个))
这样的时间复杂度是$O(m*n^2)$的,代码的写法在代码1中
接下来我们做一些优化。
首先把数组的第二维改成滚动数组。
然后令F[i][j]=max(f[1..i][j]);
这样在做第二层的转移的时候f[i][j]就能直接用F[i-1][j-1]做转移了
当然也不用非得再重开一个新的数组。
在f[i][j]做完转移之后把它改成前缀的最大值就行。(注意一定要做完转移之后再改变,因为f[i][j]在转移的时候用到了f[i-1][j])
这样在做转移的时候就少掉了O(N)的一次枚举了
复杂度变成O(n*m)的了.详见代码2
【代码1】
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e6;
const int M = 30;
int f[N+10][M+10],a[N+10];
int n,m;
int main(){
while (~scanf("%d%d",&m,&n)){
for (int i = 1;i <=n;i++) scanf("%d",&a[i]);
for(int l = 1;l <= m;l++){
for (int i = l;i <= n;i++){
if (i==l){
f[i][l] = f[i-1][l-1]+a[i];
}else{
f[i][l] = f[i-1][l]+a[i];//和第l段合并
//printf("%d ",f[i][l]);
//自己独立成段
for (int k = l-1;k <= i-1;k++)
f[i][l] = max(f[i][l],f[k][l-1]+a[i]);
}
}
}
int ans = f[m][m];
for (int i = m+1;i <= n;i++) ans = max(ans,f[i][m]);
printf("%d\n",ans);
}
return 0;
}
【代码2】
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e6;
const int M = 30;
int f[N+10][2],a[N+10];
int n,m;
int main(){
while (~scanf("%d%d",&m,&n)){
for (int i = 1;i <=n;i++) scanf("%d",&a[i]);
memset(f,0,sizeof f);
for(int l = 1;l <= m;l++){
for (int i = l;i <= n;i++){
if (i==l){
f[i][l&1] = f[i-1][(l-1)&1]+a[i];
}else{
f[i][l&1] = f[i-1][l&1]+a[i];//和第l段合并
//printf("%d ",f[i][l]);
//自己独立成段
f[i][l&1] = max(f[i][l&1],f[i-1][(l-1)&1]+a[i]);
}
}
for (int i = l+1;i <= n;i++)
f[i][l&1] = max(f[i][l&1],f[i-1][l&1]);
}
printf("%d\n",f[n][m&1]);
}
return 0;
}
【书上讲解】最大m段子段和问题的更多相关文章
- JAVA理解逻辑程序的书上全部重要的习题
今天随便翻翻看以前学过JAVA理解逻辑程序的书上全部练习,为了一些刚学的学弟学妹,所以呢就把这些作为共享了. 希望对初学的学弟学妹有所帮助! 例子:升级“我行我素购物管理系统”,实现购物结算功能 代码 ...
- 洛谷P1121 环状最大两段子段和
题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的第一行是一个正整数N,表示了序列 ...
- 洛谷 P1121 环状最大两段子段和 解题报告
P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为\(A_1\)和\(A_N\)是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 第一行是一个正整数 ...
- P1121 环状最大两段子段和
P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的 ...
- 【u124】环状最大两段子段和
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. ...
- java核心编程书上的一个错误
书上说这段代码说明了java对对象不是采用的按引用调用 这明显错了,java还是引用传递,只是把引用对象的变量复制了,互换了x,y所指的对象,对a,b没有影响
- 最大m段子段和 Day9 - E - Max Sum Plus Plus HDU - 1024
Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we ...
- c++编程思想(四)--对象和隐藏(感觉书上有误)
c++编程思想里数据抽象和隐藏实现实际就是通常所说的类和封装: 封装,继承,多态对象特点说的很多,就不再说了 关于封装,本人觉得书上有个地方写的有问题,p145和p153都提到Y::f(X*)引用了X ...
- OK 开始实践书上的项目一:即使标记
OK 开始实践书上的项目一:及时标记 然而....又得往前面看啦! ----------------------我是分割线------------------------ 代码改变世界
随机推荐
- LC: 404.左叶子节点
计算给定二叉树的所有左叶子之和. 示例: / \ 9 20 / \ 15 7 ,所以返回 24 解析 我们需要找到这样的节点 属于叶子节点 属于父节点的左子节点 方法一:用栈,dfs遍历,用全局变量r ...
- 【leetcode】926.Flip String to Monotone Increasing
题目如下: A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possib ...
- PWM输出,呼吸灯
一.初始化GPIO 使用PB1,查芯片手册对应TIM3_CH4 GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2 ...
- php 后台转发和重定向的区别及kohana框架当前url加参数方式
1.重定向是浏览器行为,浏览器地址有变化:转发是后台服务器完成, url地址不变化. 2.kohana获取URL 当前url是http://soyoung.kohana.com/blog/add?id ...
- React的contextType的使用方法简介
上一篇介绍了Context的使用方法.但是Context会让组件变得不纯粹,因为依赖了全局变量.所以这决定了Context一般不会大规模的使用.所以一般在一个组件中使用一个Context就好. 由于C ...
- 微信小程序学习笔记(四)--框架-视图层
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件.事件系统,可以构建出页面的结构. 数据绑定 使用{{}}绑定数据. 简单绑定 <view clas ...
- 转载:@RequestParam @RequestBody @PathVariable 等参数绑定注解详解
转载自:https://blog.csdn.net/walkerjong/article/details/7946109#commentBox 因为写的很好很全,所以转载过来 引言:接上一篇文章, ...
- 三种做法:BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster
目录 题意 思路 AC_Code1 AC_Code2 AC_Code3 参考 @(bzoj 2780: [Spoj]8093 Sevenk Love Oimaster) 题意 链接:here 有\(n ...
- 把多个JavaScript函数绑定到onload事件处理函数上的技巧
一,onload事件发生条件 用户进入页面且页面所有元素都加载完毕.如果在页面的初始位置添加一个JavaScript函数,由于文档没有加载完毕,DOM不完整,可能导致函数执行错误或者达不到我们想要的效 ...
- 27-python基础-python3-异常处理(try except)
到目前为止,在 Python 程序中遇到错误,或“异常”,意味着整个程序崩溃.不希望这发生在真实世界的程序中. 相反,希望程序能检测错误,处理它们,然后继续运行. 实例1: 当试图用一个数除以零时 ...