51nod 1049 1049 最大子段和 (dp)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049
令 dp[i]表示为以a[i]结尾的最大子段和,则 dp[i]=max(dp[i-1]+a[i],a[i]);
包含a[i-1] : dp[i]=dp[i-1]+a[i];
不包含a[i-1] : dp[i]=a[i];
然后扫一遍dp[i]求出最大值。 时间复杂度O(n),空间复杂度 O(n);
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>
#pragma comment(linker, "/STACK:102400000,102400000")
#define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("b.txt", "w", stdout);
#define maxn 1000000000
#define N 50010
#define mod 1000000000
using namespace std; ll dp[N];
ll f[N]; int main()
{
int n;
scanf("%d",&n);
for(int i=;i<n;i++) scanf("%lld",&f[i]);
dp[]=f[];
for(int i=;i<n;i++)
dp[i]=max(dp[i-]+f[i],f[i]);
ll m=;
for(int i=;i<n;i++)
if(dp[i]>m) m=dp[i];
printf("%lld\n",m);
return ;
}
可以发现其实 dp数组是不用保存的,我只要每次都更新一个最大值即可。空间复杂度可以优化成 O(1) .
#include<cstdio>
#include<algorithm>
using namespace std; int main()
{
int n;
long long a,ans=,m=;
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%lld",&a);
ans=max(ans+a,a);
m=max(m,ans);
}
printf("%d\n",m);
return ;
}
更快速的方法是不断读取 数组元素 a,然后sum累加a,更新最大值,如果小于0,就置为0.这样省去调用库函数的时间。
#include<stdio.h>
int main()
{
__int64 sum,sum1,tem;
sum=sum1=;
__int64 t,i;
scanf("%I64d",&t);
for(i=;i<t;i++)
{
scanf("%I64d",&tem);
sum1=sum1+tem;
if(sum1<)
sum1=;
if(sum1>sum)
sum=sum1; }
printf("%I64d\n",sum);
}
保存最大字段和的起始和终止位置。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>
#pragma comment(linker, "/STACK:102400000,102400000")
#define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("b.txt", "w", stdout);
#define maxn 1000000000
#define N 50010
#define mod 1000000000
using namespace std; int main()
{
int n;
long long a,ans=,m=;
int begin,left,right;
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%lld",&a);
if(ans>=)
{
ans+=a;
}
else
{
ans=a;
begin=i;
}
if(ans>m)
{
left=begin;
right=i;
m=ans;
}
}
printf("%d %d %lld\n",left,right,m);
return ;
}
51nod 1049 1049 最大子段和 (dp)的更多相关文章
- 51nod 1065 最小正子段和
题目链接:51nod 1065 最小正子段和 房教说用前缀和做,然后看了别人博客懂了后就感觉,这个真有意思... #include<cstdio> #include<cstring& ...
- 51nod 1293 球与切换器 | DP
51nod 1293 球与切换器 | DP 题面 有N行M列的正方形盒子.每个盒子有三种状态0, -1, +1.球从盒子上边或左边进入盒子,从下边或右边离开盒子.规则: 如果盒子的模式是-1,则进入它 ...
- 51Nod 1049:最大子段和(dp)
1049 最大子段和 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 N个整数组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+ ...
- 51nod 1051 最大子矩阵和 【最大子段和DP变形/降维】
[题目]: 一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值. 例如:*3的矩阵: - - - - 和最大的子矩阵是: - - Input 第1行:M和N, ...
- 51Nod 1050 循环数组最大子段和 | DP
Input示例 6 -2 11 -4 13 -5 -2 Output示例 20 分析: 有两种可能,第一种为正常从[1 - n]序列中的最大子字段和:第二种为数组的total_sum - ([1-n] ...
- bzoj 1049: [HAOI2006]数字序列【dp+二分+瞎搞】
第一问明显就是用b[i]=a[i]-i来做最长不下降子序列 然后第二问,对于一对f[i]=f[j]+1的(i,j),中间的数一定要改的,并且是等于b[i]或者b[j],我不会证,然后因为是随机数据,所 ...
- 51nod 循环数组最大子段和
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 对于普通的数组,只要求一次最大子段和即可.但是这题是可以循环的,所 ...
- 51nod 1051 最大子矩阵和(dp)
题目链接:51nod 1051 最大子矩阵和 实质是把最大子段和扩展到二维.读题注意m,n... #include<cstdio> #include<cstring> #inc ...
- 51nod 1412 AVL树的种类(dp)
题目链接:51nod 1412 AVL树的种类 开始做的时候把深度开得过小了结果一直WA,是我天真了.. #include<cstdio> #include<cstring> ...
随机推荐
- Effective Java总结
规则1. 用静态工厂方法代替构造器 例子: public class Example { } public class StaticFactory { //valueOf/Of/getInstance ...
- c++new和new()区别(了解)
我们在C++程序中经常看到两种new的使用方式:new A以及new A().那么这两种究竟有什么区别呢? 调用new分配的内存有时候会被初始化,而有时候不会,这依赖于A的类型是否是POD(Plain ...
- eclipse中本地项目怎么和svn中的项目关联?
网速不好,通过别的方式把项目下载到本地硬盘,然后导入eclipse,代码修改后怎么提交到svn呢? 这个纠结了好久的问题... 首先要确定eclipse中安装了svn插件. 然后在“svn资源库研究” ...
- C# 序列化 Serialize 的应用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...
- LCT小结
LCT真是灵活好用… LCT的基本思想与树链剖分差不多,都是把树剖成一条条链,只不过LCT用的是SPLAY维护的,而且,SPLAY的链是会变化的,不像剖分是定死的. LCT最重要的操作就是access ...
- Java 延时常见的几种方法
1. 用Thread就不会iu无法终止 new Thread(new Runnable() { public void run() { while (true) { test(); try { Thr ...
- 【mysql5.6】SQL基础
我买了本深入浅出MySQL, 记录一下笔记. 一.数据定义语言(DDL) 1.创建数据库 create database name; 2.显示所有的数据库 show databases; 3.选择 ...
- Javascript scrollTop 20大洋
花了20大洋,买了一个视频,这是读书笔记 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"&g ...
- 2014多校第六场 1007 || HDU 4927 Series 1(杨辉三角组合数)
题目链接 题意 : n个数,每操作一次就变成n-1个数,最后变成一个数,输出这个数,操作是指后一个数减前一个数得到的数写下来. 思路 : 找出几个数,算得时候先不要算出来,用式子代替,例如: 1 2 ...
- IDT hook KiTrap03
关于idt的基本知识就不进行赘述了,先看一个例子 0 ;------->进入内核,找到中断处理例程KiTrap03 0 这段代码执行,触发3号中断,然后开始执行KiTrap03例程,要知道,执行 ...