POJ2479 - Maximum sum (动规)
2015-08-30 01:39
260 查看
题目链接 : poj2479 - Maximum sum
思路
最大连续子列和
代码
思路
题目要求的是,两段不相交的连续子列,使其加和最大。基础问题就是最大连续子列和,只要分别求得正序和逆序的最大和,然后枚举一边中间点,就可以得到结果。最大连续子列和
解法有多种,这里用一种比较简单的动规的方法。另一种思路令 num[i]num[i] 表示序列中第 i 个数字, F(i)F(i) 为以第 i 个数字结尾的序列中最大的和, 那么
F(1)=num[1] { F(i)=F(i−1)+num[i], F(i−1)>0 F(i)=num[i], F(i−1)<=0
\ F(1) = num[1] \
\begin{cases}
\ F(i) = F(i-1) + num[i],\ \ \ \ F(i-1)>0 \\
\ F(i) = num[i],\ \ \ \ F(i-1)<=0
\end{cases}
根据题意,我们需要的 F(i)F(i) 是第 i 个数字之前的连续子列和的最大值,我们需要从头到尾更新一次
for(int i=2; i=n; i++) f(i) = max( f(i), f(i-2) );
代码
#include <iostream> #include <cstdio> #include <algorithm> const int inf = 0x7ffffff; using namespace std; int num[50010], s[50010], e[50010]; int main() { int t, n, maxsum, sum; scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", num+i); s[1] = num[1]; for(int i=2; i<=n; i++) { if(s[i-1]>0) s[i] = s[i-1] + num[i]; else s[i] = num[i]; } for(int i=2; i<=n; i++) s[i] = max(s[i], s[i-1]); e = num ; for(int i=n-1; i>=1; i--) { if(e[i+1]>0) e[i] = e[i+1] + num[i]; else e[i] = num[i]; } for(int i=n-1; i>=1; i--) e[i] = max(e[i+1], e[i]); maxsum = -inf; for(int i=1; i<n; i++) { sum = s[i] + e[i+1]; if(sum>maxsum) maxsum = sum; } printf("%d\n", maxsum); } }
相关文章推荐
- POJ2709 - Painter (贪心)
- 初步02-长方形的周长和面积
- 弹窗加密代码(可关闭)
- 2015.8.23作业 Linux命令学习
- MAC下使用feddler进行抓包
- POJ3264 - Balanced Lineup (线段树 基本操作)
- HDU 4408 Minimum Spanning Tree (图的最小生成树计数 Kruskal + Matrix_Tree定理)
- POJ3468 - A Simple Problem with Integers (线段树 区间更新)
- Ubuntu下Tomcat初始配置
- UVa11582 - Colossal Fibonacci Numbersl (打表找规律)
- FastJson的使用
- HDU5024--Wang Xifeng's Little Plot(DFS) 4000
- jQuery div层渐入渐出效果
- 线程 相关知识(二)
- TreeSet倒序
- mysql-5.6.19-winx64免安装版配置
- Android-Service(系统服务实例:定位,网络判断,电话服务 ,通知栏通知等)
- Batsing的网页编程规范(HTML/CSS/JS/PHP)
- 初步01-输出点阵图
- 原创科幻短篇《高考》