虽然是两个水题,但是一次AC的感觉真心不错

这个问题算是maximum-subarray问题的升级版,不过主要算法思想不变:

1. maximum-subarray问题

maximum-subarray就是找到数组A[1....n]中的连续子数组A[i.....j]并且A[i]+...+A[j]和最大。当然了,(1<=i<=j<=n)。

maximum-subarray的O(n)解法就是从左到右扫描数组A,另外设置一工具数组DP,DP数组的作用就是记录以当前下标为终止下标的子数组和。比如DP[j]=A[i]+....+A[j](A[i] 到 A[j]是连续的)。现在假设我们已经求出DP[j],数组即将扫描A[j+1],则DP[j]与DP[j+1]的关系描述如下:

DP[j+1]=(DP[j]>0)? (DP[j]+A[j+1]) : (A[j+1]).

因为DP[j+1]要求出以j+1下标为结束下标的子数组和,而且DP[j]已经求出,所以我们要判断DP[j]是否为正数,如为正,则加上A[j+1]。如为负,那么很明显的,A[i]+.....+A[j]+A[j+1]<A[j+1], 所以要让DP[j+1]=A[j+1]。

2. 求两个maximum-subarray问题

这两个maximum-subarray不相交。

我们可以设置一个“分水岭”,假设为k,那么maximum-subarray(A[1..k]) + maximum-subarray(A[k+1..n])就是我们要的解。

当然如果我们枚举每一个k值(1<=k<=n-1)的话,因为题目开出的N值为50000,真个时间复杂度为O(n^2),必然超时。

所以我们可以再设两个工具数组:lmax和rmax,lmax[i]表示A[1]到A[i]的最大子数组和,rmax[i]=A[i+1]....A[n]的最大子数组和。再次明确一下:lmax/rmax数组与DP数组的不同。

假设DP[s]=A[p+..q+..+r+..s], 那么lmax[s]可能就等于A[q+...+r]或者A[p+...+r]或者等等。

然后我们得到每个lmax[k]+rmax[k],对k进行枚举,lmax[k]+rmax[k]值最大的即为最后的解。

附上POJ2593代码:(POJ2479改动一点就可以了)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
const int max_size=;
int n,a[max_size];
int ldp[max_size],rdp[max_size],ans,inf=<<;
int lmax[max_size],rmax[max_size];
int main(){
while(scanf("%d",&n)!=EOF&&n){
memset(a,,sizeof(a));
memset(ldp,,sizeof(ldp));
memset(rdp,,sizeof(rdp));
memset(lmax,,sizeof(lmax));
memset(rmax,,sizeof(rmax));
ans=-inf;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
lmax[]=ldp[]=a[];
for(int i=;i<=n;i++){
if(ldp[i-]>) ldp[i]=ldp[i-]+a[i];
else ldp[i]=a[i];
ans=max(ans,ldp[i]);
lmax[i]=ans;
} rmax[n]=rdp[n]=a[n];
ans=-inf;
for(int i=n-;i>=;i--){
if(rdp[i+]>) rdp[i]=rdp[i+]+a[i];
else rdp[i]=a[i];
ans=max(ans,rdp[i]);
rmax[i]=ans;
}
ans=-inf;
for(int k=;k<=n-;k++){
ans=max(ans,lmax[k]+rmax[k+]);
}
printf("%d\n",ans);
}
}

POJ2479,2593: 两段maximum-subarray问题的更多相关文章

  1. poj 2593&&poj2479(最大两子段和)

    Max Sequence Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 16850   Accepted: 7054 Des ...

  2. Leetcode#53.Maximum Subarray(最大子序和)

    题目描述 给定一个序列(至少含有 1 个数),从该序列中寻找一个连续的子序列,使得子序列的和最大. 例如,给定序列 [-2,1,-3,4,-1,2,1,-5,4], 连续子序列 [4,-1,2,1] ...

  3. 【LeetCode】53. Maximum Subarray (2 solutions)

    Maximum Subarray Find the contiguous subarray within an array (containing at least one number) which ...

  4. 【LeetCode】最大子阵列 Maximum Subarray(贪婪&分治)

    描述: Given an integer array nums, find the contiguous subarray (containing at least one number) which ...

  5. 【leetcode】Maximum Subarray (53)

    1.   Maximum Subarray (#53) Find the contiguous subarray within an array (containing at least one nu ...

  6. 算法:寻找maximum subarray

    <算法导论>一书中演示分治算法的第二个例子,第一个例子是递归排序,较为简单.寻找maximum subarray稍微复杂点. 题目是这样的:给定序列x = [1, -4, 4, 4, 5, ...

  7. leetCode 53.Maximum Subarray (子数组的最大和) 解题思路方法

    Maximum Subarray  Find the contiguous subarray within an array (containing at least one number) whic ...

  8. Maximum Subarray / Best Time To Buy And Sell Stock 与 prefixNum

    这两个系列的题目其实是同一套题,可以互相转换. 首先我们定义一个数组: prefixSum (前序和数组) Given nums: [1, 2, -2, 3] prefixSum: [0, 1, 3, ...

  9. LeetCode 53. Maximum Subarray(最大的子数组)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

随机推荐

  1. python获取系统时间

    import time print time.time() 输出的结果是: 1279578704.6725271 但是这样是一连串的数字不是我们想要的结果,我们可以利用time模块的格式化时间的方法来 ...

  2. Python设计模式——工厂方法模式(FactoryMethod)

    需求:有一个学雷锋活动,有买米和扫地两个内容,参与的人有大学生和社区志愿者,他们各自的方法不一样. 如果用简单工厂模式实现: #encoding=utf-8 __author__ = 'kevinlu ...

  3. extern "C"的作用

    一.概述 在C语言的头文件中,经常可以看到如下的代码,那这个是什么作用呢? #ifdef __cplusplus extern "C" { #endif /*...*/ #ifde ...

  4. Pair Project: Elevator Scheduler [电梯调度算法的实现和测试][关于电梯调度算法的附加思考]:刘耀先-11061183,罗凡-11061174

    本文为对于电梯调度算法的三个附加题思考 1.改进电梯调度的interface 设计, 让它更好地反映现实, 更能让学生练习算法, 更好地实现信息隐藏和信息共享. <1>进一步提高API定义 ...

  5. java.io.IOException: Cannot run program "bash": error=12, Cannot allocate memory

    java.io.IOException: Cannot run program , Cannot allocate memory 云服务器运行nutch报出的异常: 解决方案: http://daim ...

  6. HDU 2844 Coins(多重背包)

    点我看题目 题意 :Whuacmers有n种硬币,分别是面值为A1,A2,.....,An,每一种面值的硬币的数量分别是C1,C2,......,Cn,Whuacmers想买钱包,但是想给人家刚好的钱 ...

  7. HDU 1166 敌兵布阵(线段树 单点更新)

     点我看题目  题意 :HDU的中文题也不常见....这道题我就不详述了..... 思路 :这个题用线段树用树状数组都可以,用线段树的时候要注意输入那个地方,输入一个字符串的时候不要紧接着输入两个数字 ...

  8. 为tomcat启用nio机制

    tomcat的运行模式有3种.修改他们的运行模式.3种模式的运行是否成功,可以看他的启动控制台,或者启动日志.或者登录他们的默认页面http://localhost:8080/查看其中的服务器状态. ...

  9. SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-003-Spring对AOP支持情况的介绍

    一. 不同的Aop框架在支持aspect何时.如何织入到目标中是不一样的.如AspectJ和Jboss支持在构造函数和field被修改时织入,但spring不支持,spring只支持一般method的 ...

  10. ANDROID_MARS学习笔记_S02_005_AppWidget1

    一.AppWidget介绍 1.要在手机生成AppWidget需的东西 (1)AppWidgetProviderInfo a).res\xml\example_appwidget_info.xml b ...