N 组连续子串最大和
数组 a 中有 M 个数 , 将 M 个数分成 N 组 , 并且每组中的数据顺序和原数组中的顺序保持一致,求 N 组中的数据之和最大为多少?
向 dp 数组中赋初始值 ,如果 M == N ,则 dp[ i ][ i ] = dp[ i - 1 ][ i - 1 ] + a[ i ] ;
若N为1时 ,即为求连续子串最大和问题;
假设dp[ 1 ][ i ] ( 2 =< i <= M) 代表 与第 i 个数组成连续子串的最大和,当dp[ 1 ][ i - 1 ] < 0 时 , a[ i ] 独立作为一个子串 , 即 dp[ 1 ][ i ] = max ( dp[ 1 ][ i -1 ] + a[ i ] , a[ i ] ) ;很需要注意的一点是:dp[ 1 ][ i ] 不一定是 i 个数中连续子串的最大和。
分别求出数组中有一个数、两个数、三个数……M个数中连续子串的最大和,用dp[ i ][ 1 ] 来表示;
若N为2时,表示将M个数分成 2 组 ,求两组数中的和最大 ;
dp[ 2 ][ i ] ( 3 =< i <= M ) 代表 与第 i 个数组成连续子串,形成两个连续子串中,第2个子串的最大和;
可知,第二个子串可以单独成为一段,最终形成两段,也可以和上一个段一起形成一段,最终形成两段;
所以 dp[M][N] 代表 与第M个数组成的连续子串的最大和,但不一定是 M 个数中连续子串的最大和 ;
与第 M 个数组成连续子串时 ,第 M 个数可以与第 M-1 个数组成的子串组合,也可以独立作为一个子串 , 与 M-1 个数组成的(N-1)组连续子串中最大和组合 ,才能达到分成 N 组的效果;
最后输出dp数组中最大值,即为 N 组中数据之和的最大值;
下面给出相应的代码:
#include<iostream>
using namespace std ;
#define M 100005
#define max(x,y) ((x) > (y) ? (x) : (y))
int a[ M ] , dp[ M ][ M ] ;
int main() {
int k , n ;
while(cin >> k >> n) {
int i ;
for(i = 1 ; i <= n ; i++)
cin >> a[i] ;
memset(dp,0,sizeof(dp)) ;
for(i = 1 ; i <= k ; i++) {
dp[i][i] = dp[i-1][i-1] + a[i] ;
dp[i-1][i] = max(dp[i-1][i],dp[i-1][i-1]) ;
for(int j = i + 1 ; j <= n ; j++) {
dp[i][j] = max(dp[i-1][j-1]+a[j],dp[i][j-1]+a[j]) ;
dp[i-1][j] = max(dp[i-1][j],dp[i-1][j-1]) ;
}
}
int max1 = -(1<<30) ;
for(i = k ; i <= n ; i++)
max1 = max(max1,dp[k][i]) ;
cout << max1 << endl ;
}
return 0 ;
}
上面的代码空间复杂度比较高,但通过观察可以得到,依照滚动数组的思想,让dp数组的行数为2,在两行中循环,这样轻易一改,省去了很多空间:
有木有很强大!!! 思维决定到效率!!!
#include<iostream>
using namespace std ;
#define M 100005
#define max(x,y) ((x) > (y) ? (x) : (y))
int a[ M ] , dp[ 2 ][ M ] ;
int main() {
int k , n ;
while(cin >> k >> n) {
int i ;
for(i = 1 ; i <= n ; i++)
cin >> a[i] ;
memset(dp,0,sizeof(dp)) ;
int t = 0 ;
for(i = 1 ; i <= k ; i++) {
t = !t ;
dp[t][i] = dp[!t][i-1] + a[i] ;
dp[!t][i] = max(dp[!t][i],dp[!t][i-1]) ;
for(int j = i + 1 ; j <= n ; j++) {
dp[t][j] = max(dp[!t][j-1]+a[j],dp[t][j-1]+a[j]) ;
dp[!t][j] = max(dp[!t][j],dp[!t][j-1]) ;
}
}
int max1 = -(1<<30) ;
for(i = k ; i <= n ; i++)
max1 = max(max1,dp[k&1][i]) ;
cout << max1 << endl ;
}
return 0 ;
}
N 组连续子串最大和的更多相关文章
- ZZNU-oj-2141:2333--【O(N)求一个数字串能整除3的连续子串的个数,前缀和数组+对3取余组合数找规律】
2141: 2333 题目描述 “别人总说我瓜,其实我一点也不瓜,大多数时候我都机智的一批“ 宝儿姐考察你一道很简单的题目.给你一个数字串,你能判断有多少个连续子串能整除3吗? 输入 多实例输入,以E ...
- HDU-1231 简单dp,连续子序列最大和,水
1.HDU-1231 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231 3.总结:水 题意:连续子序列最大和 #include<iostre ...
- poj 3518 Corporate Identity 后缀数组->多字符串最长相同连续子串
题目链接 题意:输入N(2 <= N <= 4000)个长度不超过200的字符串,输出字典序最小的最长公共连续子串; 思路:将所有的字符串中间加上分隔符,注:分隔符只需要和输入的字符不同, ...
- 3 Longest Substring Without Repeating Characters(最长不重复连续子串Medium)
题目意思:求字符串中,最长不重复连续子串 思路:使用hashmap,发现unordered_map会比map快,设置一个起始位置,计算长度时,去减起始位置的值 eg:a,b,c,d,e,c,b,a,e ...
- 连续子序列最大和的O(NlogN)算法
对于一个数组,例如:int[] a = {4,-3,5,-2,-1,2,6,-2}找出一个连续子序列,对于任意的i和j,使得a[i]+a[i+1]+a[i+2]+.......+a[j]他的和是所有子 ...
- 【ToReadList】六种姿势拿下连续子序列最大和问题,附伪代码(以HDU 1003 1231为例)(转载)
问题描述: 连续子序列最大和,其实就是求一个序列中连续的子序列中元素和最大的那个. 比如例如给定序列: { -2, 11, -4, 13, -5, -2 } 其最大连续子序列为{ 11, ...
- 剑指Offer-连续子数组中的最大和
题目 输入一个整型数组,数组里有正数也有负数.数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为 O(n). 输入 [1,-2,3,10,-4,7,2,-5] 返回值 ...
- 【NOIP2015提高组】子串
https://daniu.luogu.org/problem/show?pid=2679 看到方案数问题直觉就能想到DP,考虑用f(i,j,k)表示A[1...i]取k个子串组成B[1...j]的方 ...
- 【NOIP】提高组2015 子串
[题意]求从字符串A中取出k个互不重叠的非空子串顺序拼接形成B的方案数.n<=1000,m<=100,k<=m. [算法]动态规划 [题解]这题主要是将从i-l转移变成从i-1转移, ...
随机推荐
- 2014ACM/ICPC亚洲区广州站 Song Jiang's rank list
欢迎参加——每周六晚的BestCoder(有米!) Song Jiang's rank list Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- 【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst
题目大意: 2个操作 A.区间a b 增加 c B 查询a b; 注意事项:1.记住要清除标记 2.查询时要下放标记,但没必要向上更新 线段:自带的,不用建模 区间和性质:sum: /* WA 1次 ...
- cookie的expires属性和max-age属性
expires属性 指 定了coolie的生存期,默认情况下coolie是暂时存在的,他们存储的值只在浏览器会话期间存在,当用户推出浏览器后这些值也会丢失,如果想让 cookie存在一段时间,就要为e ...
- 在SQL Server 2008 中使用SQL脚本创建登录用户并授权
到处都使用超级用户sa显然是不安全的,因此有创建用户并让其只能访问某个数据库的必要.当然可以使用SQL Server自带的图形界面向导,但是太难用用了!有时候代码比较直接,比如这里: --使用已经创建 ...
- oracle tablespace
oracle tablespace 1. 查看所有表空间大小 SQL> select tablespace_name,sum(bytes)/1024/1024 from dba_data_fil ...
- js基础——cssText
以前,只知道设置css里的属性都是通过 元素.style.属性名 = 属性值 的方式,此时经常遇到的情况就是类似这样: var head= document.getElementById(&quo ...
- 深入理解Java虚拟机:OutOfMemory实战
在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(下文称OOM)异常的可能,本节将通过若干实例来验证异常发生的场景.并且会初步介绍 ...
- Windows vista以上模拟Alt Ctrl Delete
之前客户要求我们能够在windows登陆界面能够用指定账户批量控制机器登陆,然后用windows credentials provider(vista以上,xp需要用Gina)实现了这个功能,这期间遇 ...
- c++中basic_istream::getline()的返回值何时为真
今天在看primer,17ch中的IO库再探,做课后练习,要求用ifstream.getline(char*, const unsigned, char)读取一个文件,用循环: while(ifs.g ...
- Java并发编程实践(读书笔记) 任务执行(未完)
任务的定义 大多数并发程序都是围绕任务进行管理的.任务就是抽象和离散的工作单元. 任务的执行策略 1.顺序的执行任务 这种策略的特点是一般只有按顺序处理到来的任务.一次只能处理一个任务,后来其它任 ...