【动规递推】最大数列
来源:互联网 发布:python in用法 编辑:程序博客网 时间:2024/06/05 13:21
最大数列
(sequence.pas/c/cpp)
【问题描述】
有一个N项的数列a1, a2 ... aN (|ai| <=10000, 1 <= i <= N)。S定义为
你的任务是求S的值,即为求一个序列的两个不相交子序列的最大和。
【输入文件】
输入文件sequence.in的第一行是一个整数N(2 <= N <= 100000),表示数列的项数。第二行有n个整数,用空格分隔,第i个整数Ai(|Ai| <=10000)是第i位数。
【输出文件】
输出文件sequence.out包括一行,这一行只包含一个整数,就是S。
【样例输入】
5
-5 9 -5 11 20
【样例输出】
40
【数据规模】
对于30%的数据,保证有n <= 80;
对于70%的数据,保证有n <= 10000;
对于全部的数据,保证有n <= 100000。
先看求一个最大子列的做法:
Sum := 0; min := 0;For i := 1 to n do begin sum := sum + a[i]; if sum – min > ans then ans := sum – min; if min < sum then sum := min; end;
上述算法实质:动态规划,复杂度O(N)
下面看求两个子列的情况:
两个子列不相交,故一定存在一个断点,我们枚举断点,然后分别对左边数列和右边的数列套用上述求一个最大子列的方法。算法复杂度O(N2)
需要进行优化,我们可以一开始就求出所有前缀子列的最大子列和所有后缀子列的最大子列,然后存放在一个数组里,后部计算则可直接调用。
For I := 1 to n-1 do ans := max(ans,left[i]+right[i+1]);
因为求一个最大子列的方法事实上是在递推,所以left和right数组都可以在O(N)的时间内求出。整个算法复杂度也是O(N)
Pascal Code
program sequence;var n:longint; a,s,ss,f:array[0..100000+10] of longint;procedure init;begin assign(input,'sequence.in'); assign(output,'sequence.out'); reset(input); rewrite(output);end;procedure outit;begin close(input); close(output); halt;end;procedure readdata;var i:longint;begin read(n); for i:=1 to n do begin read(a[i]); s[i]:=s[i-1]+a[i]; end; for i:=n downto 1 do ss[i]:=ss[i+1]+a[i];end;procedure main;var min,max,ans:longint; i:longint;begin min:=0;f[0]:=-maxlongint; for i:=1 to n do//求左区间的最大值 begin f[i]:=s[i]-min; if f[i]<f[i-1] then f[i]:=f[i-1]; if min>s[i] then min:=s[i]; end; min:=0;max:=-maxlongint;ans:=-maxlongint; for i:=n downto 2 do//求右区间的最大值 顺便把左区间相加 找出最佳答案 begin //后面用到 f[i-1] 所以只能 downto 2 if max<ss[i]-min then max:=ss[i]-min; if max+f[i-1]>ans then ans:=max+f[i-1]; if min>ss[i] then min:=ss[i]; end; writeln(ans);end;begin init; readdata; main; outit;end.
- 【动规递推】最大数列
- 【动态规划】最大数列
- 最大递增子数列
- 最大子数列和
- 最大连续数列和
- 最大连续子数列
- 子数列的最大和
- 最大连续子数列和
- 最大连续数列的和
- 最大连续数列的和
- 最大连续数列的和
- 最大连续数列的和
- 最大连续数列的和
- 最大连续数列的和
- 最大连续数列的和
- 最大连续子数列和
- 不连续数列的最大和、最大连续数列和、最大间隔环
- 最大连续子数列和问题
- 【动规递推】Mobile Service
- 公司面试题目之取出数据库中重复的记录
- 【带权中位数】YL杯超级篮球赛
- 带权中位数
- 【带权中位数】安装服务器
- 【动规递推】最大数列
- 【动规递推】迷宫
- 【字符串处理】【模拟】NBA工资
- 【动规】【二分】划分数列
- 【模拟】【打表】无聊的游戏
- 【动规递推】暴走的猴子
- java基础
- 【最短路】【NOIP2001】CAR的旅行路线
- 【动规递推】【NOIP2001】统计单词个数