17089 最大m子段和(scauoj、dp动态规划)
来源:互联网 发布:数据库表空间导出 编辑:程序博客网 时间:2024/06/05 19:50
题目描述:
Description
“最大m子段和”问题:给定由n个整数(可能为负)组成的序列a1、a2、a3、...、an,以及一个正整数m,要求确定序列的m个不相交子段,使这m个子段的总和最大!m是子段的个数。
输入格式
第一行:n和m; (n,m<10000)第二行:n个元素序列,中间都是空格相连。比如:6 32 3 -7 6 4 -5
输出格式
输出最大m子段和。比如:15这15可由这三个段之和来的:(2 3) -7 (6) (4) -5
输入样例
6 32 3 -7 6 4 -5
输出样例
15
题目分析:
像这种找子串的问题,一般的入手点都是前n个元素分割为m个划分,然后堆出公式,这一题同样适用,不过可能会麻烦一点。
我们假设s[i][j]为序列a前j个元素有i个子段的最大结果且a[j]是在第i个子段之中的,那么接下来就是分情况:a[j-1]在第i个子段中、a[j-1]不在第i个子段中(即a[j]是第i个子段的开头),我们可以按这样的分析建立公式:
s[i][j]=max{s[i][j-1]+a[j],max{s[i-1][k]}+a[j]}
其中1<=i<=m,i<=j<=n,i-1<=k<j
然后写代码的时候记得初始化一些特殊项就可以了。
但是我们可以看到,当n和m很大时很容易内存溢出(爆栈),所以我们可以换一种方式来写,就是把二维数组化成一维数组,这部分我看了书才明白怎么写比较精简,还是学的不够啊,接下来放优化后AC的代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;int main(){ int s[10000],v[10000],a[10000]; int n,m,sum=0; memset(s,0,sizeof(s)); memset(v,0,sizeof(v)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); s[0]=0;v[1]=0; for(int i=1;i<=m;i++) { s[i]=s[i-1]+a[i]; v[i-1]=s[i]; int maxx=s[i]; int j; for(j=i+1;j<=n;j++) { if(s[j-1]>v[j-1]) { s[j]=s[j-1]+a[j]; } else s[j]=v[j-1]+a[j]; v[j-1]=maxx; if(maxx<s[j]) maxx=s[j]; } v[j-1]=maxx; } for(int i=m;i<=n;i++) if(sum<s[i]) sum=s[i]; printf("%d",sum);}
阅读全文
0 0
- 17089 最大m子段和(scauoj、dp动态规划)
- 【动态规划】最大m子段和
- 环形m段最大子段和 题解动态规划DP
- 动态规划---最大子段和,最大子矩阵和,最大m子段和
- 动态规划入门之最大M子段和
- 动态规划_最大m子段和
- DP动态规划--最大子段和--Max Sum
- 51nod 最大子段和(动态规划DP)
- 最大子段-n上找m个子段的和为最大-动态规划-二维dp+滚动数组dp优化
- DP最大M子段和
- 动态规划----最大子段和
- 最大子段和(动态规划)
- 最大子段和动态规划实现
- 最大子段和(动态规划)
- 动态规划 - 最大子段和
- 最大子段和-分治&&动态规划
- 动态规划求解最大子段和
- 动态规划之最大子段和
- Java虚拟机详解----JVM常见问题总结
- Get https://registry-1.docker.io/v2/library/python/manifests/2.7http: TLS handshake timeout
- 第三周学习内容
- hibernate框架一对多之放弃外键的维护(十五)
- 不得不使用的百度快照优化seo技巧
- 17089 最大m子段和(scauoj、dp动态规划)
- ubantu下彻底删除Mysql
- C#继承(四)——接口
- HDOJ2085 核反应堆
- 关于C语言函数调用汇编时参数大于4个的时候该如何传参
- C#中Linq的使用
- 【SublimeText3】输入法候选窗口跟随光标/安装插件
- 模拟实现库函数---qsort
- 数列的极限