- > 动规讲解基础讲解四——最大子段和问题
给出一个整数数组a(正负数都有),如何找出一个连续子数组(可以一个都不取,那么结果为0),使得其中的和最大?

看见这个问题你的第一反应是用什么算法?
(1) 枚举?对,枚举是万能的!枚举什么?子数组的位置!好枚举一个开头位置i,一个结尾位置j>=i,再求a[i..j]之间所有数的和,找出最大的就可以啦。好的,时间复杂度?
(1.2)枚举j,O(n)
(1.3)求和a[i..j],O(n)
for(int i = ; i <= n; i++)
{
for(int j = i; j <= n; j++)
{
int sum = ;
for(int k = i; k <= j; k++)
sum += a[k]; max = Max(max, sum);
}
}
(2.1)枚举i,O(n)
(2. 2)枚举j,O(n) ,这里我们发现a[i..j]的和不是a[i..j – 1]的和加上a[j]么?所以我们在这里当j增加1的时候把a[j]加到之前的结果上不就可以了么?对!所以我们毫不费力地降低了复杂度,得到了一个新地时间复杂度为O(n^2)的更快的算法。
for(int i = ; i <= n; i++)
{
int sum = ; for(int j = i; j <= n; j++)
{
sum += a[j];
max = Max(max, sum);
}
}
(3)分治一下?
endmax = answer = a[]
for i = to n do
endmax = max(endmax, ) + a[i]
answer = max(answer, endmax)
endfor
start =
answerstart = asnwerend =
endmax = answer = a[]
for end = to n do
if endmax > then
endmax += a[end]
else
endmax = a[end]
start = end
endif
if endmax > answer then
answer = endmax
answerstart = start
answerend = end
endif
endfor
这里我们直接用end作为循环变量,通过更新与否决定start是否改变。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long n,a[],dp,answer;
int main()
{
cin>>n;
for(int i=;i<=n;i++) cin>>a[i];
dp=answer=a[];
for(int i=;i<=n;i++){
dp=max(dp,0LL)+a[i];
answer=max(dp,answer);
}
cout<<answer;
}
如果对你有所帮助,别忘了加好评哦;么么哒!!下次见!88
- > 动规讲解基础讲解四——最大子段和问题的更多相关文章
- - > 动规讲解基础讲解一——01背包(模板)
作为动态规划的基础,01背包的思想在许多动规问题中会经常出现,so,熟练的掌握01背包的思路是极其重要的: 有n件物品,第i件物品(I = 1,2,3…n)的价值是vi, 重量是wi,我们有一个能承重 ...
- - > 动规讲解基础讲解四——矩阵取数
给定一个m行n列的矩阵,矩阵每个元素是一个正整数,你现在在左上角(第一行第一列),你需要走到右下角(第m行,第n列),每次只能朝右或者下走到相邻的位置,不能走出矩阵.走过的数的总和作为你的得分,求最大 ...
- - > 动规讲解基础讲解五——最长公共子序列问题
一些概念: (1)子序列: 一个序列A = a1,a2,……an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列. 例如: 对序列 1,3,5 ...
- - > 动规讲解基础讲解六——编辑距离问题
给定两个字符串S和T,对于T我们允许三种操作: (1) 在任意位置添加任意字符(2) 删除存在的任意字符(3) 修改任意字符 问最少操作多少次可以把字符串T变成S? 例如: S= “ABCF” ...
- - > 动规讲解基础讲解八——正整数分组
将一堆正整数分为2组,要求2组的和相差最小.例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. 整数个数n<=100,所有整数的和<=1 ...
- - > 动规讲解基础讲解七——最长单增子序列
(LIS Longest Increasing Subsequence)给定一个数列,从中删掉任意若干项剩余的序列叫做它的一个子序列,求它的最长的子序列,满足子序列中的元素是单调递增的. 例如给定序列 ...
- - > 动规讲解基础讲解三——混合背包(背包模板)
将01背包,完全背包,和多重完全背包问题结合起来,那么就是混合三种背的问题 根据三种背包的思想,那么可以得到混合三种背包的问题可以这样子求解 for(int i=1; i<=N; ++i) if ...
- 第二十四节:Java语言基础-讲解数组的综合应用
数组的综合应用 // 打印数组 public static void printArray(int[] arr) { for(int x=0;x<arr.length;x++) { if(x!= ...
- Verilog语法基础讲解之参数化设计
Verilog语法基础讲解之参数化设计 在Verilog语法中,可以实现参数化设计.所谓参数化设计,就是在一个功能模块中,对于一个常量,其值在不同的应用场合需要设置为不同的置,则将此值在设计时使用 ...
随机推荐
- C#与C++的区别(二)
这几天深入学习C#的面向对象的内容,发现C#的很多用法跟C++比起来还是有很多的不同点,头脑中知识的海洋刮起了阵阵海浪,在此继续整理一下二者的不同点,主要还是写的C#能用,而在C++中不能用的一些知识 ...
- ACM_求f(n)
求f(n) Time Limit: 2000/1000ms (Java/Others) Problem Description: 设函数f(n)=1*1*1+2*2*2+3*3*3+...+n*n*n ...
- hibernate关联关系查询
关联关系 一对一 A中包含B的对象,B中包含A的对象 一对多 A中包含B的集合,B中包含A的对象 多对多 A中包含B的集合,B中包含A的集合 1,一对多配置 一名老师可以对应多名学生 2,模型类 老师 ...
- CF 334 div.2-D Moodular Arithmetic
思路: 易知k = 0的时候答案是pp-1,k = 1的时候答案是pp. 当k >= 2的时候,f(0) = 0,对于 1 <= n <= p - 1,如果f(n)确定,由题意可知f ...
- 打开VMware Workstation,虚拟机不见了
1 打开VM,发现虚拟机不见了 如图所示: 此时先别急着再次安装虚拟机. 2 先打开设备上所有已安装过的虚拟机,看你需要的还在不在 3 总结 如果打开后发现你要的虚拟机还存在,直接打开就好.否则,就得 ...
- text-shadow的用法详解
1.兼容性:text-shadow 和 box-shadow 这两个属性在主流现代浏览器上得到了很好的支持( > Chrome 4.0, > Firefox 3.5, > Safar ...
- spring加载classpath与classpath*的区别别
1.无论是classpath还是classpath*都可以加载整个classpath下(包括jar包里面)的资源文件. 2.classpath只会返回第一个匹配的资源,查找路径是优先在项目中存在资源文 ...
- ubuntu+ngnix+thinkphp pathinfo配置
一.thinkphp 项目改为pathinfo模式 XXX/ThinkPHP/Conf/convention.php文件中找到 'URL_MODEL' => 1, // URL访问模式,可选参数 ...
- 计算型属性 vs 懒加载
只实现 getter 方法的属性被称为计算型属性,等同于 OC 中的 ReadOnly 属性 计算型属性本身不占用内存空间 不可以给计算型属性设置数值 计算型属性可以使用以下代码简写 var titl ...
- php redis使用 常用方法
基本 $redis = new Redis();//创建对象 $redis->connect('127.0.0.1',6379);//建立连接 $redis->delete('test') ...