1049 最大子段和
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
N个整数组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值。当所给的整数均为负数时和为0。
例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
Output
输出最大子段和
Input示例
6
-2
11
-4
13
-5
-2
Output示例
20
思路:
1.可以使用动态规划也可以使用分治
2.动态规划见传送门(我我我是传送门)
3.下面来分析一下使用分治思想来解决
4.把数组分为左右两段,可以猜想最大子序列不在左边这一段就是在右边这一段,当然还有跨越中间边界的情况
5.跨越中间边界的情况可以在mid点往左边扫找出最大的和,然后可以在mid点往右边扫找出最大的和,然后跨越中间边界最大的和就是他们的相加和
6.左边和右边的情况可以使用递归
贴代码:
package a51nodWeb.acm;
import java.util.Scanner;
public class M1049 {
public static long maxSub(long[] nums, int left, int right) {
if(left==right) {
if(nums[left]<0) {
return 0;
}else {
return nums[left];
}
}
int mid = (left+right)/2;
long maxL = maxSub(nums, left, mid);
long maxR = maxSub(nums, mid+1, right);
long maxLeft = 0;
long maxRight = 0;
long thisSumLeft=0;
long thisSumRight = 0;
for (int i = mid; i>=left; i--) {
thisSumLeft+=nums[i];
if(thisSumLeft>maxLeft) {
maxLeft = thisSumLeft;
}
}
for (int i = mid+1; i < nums.length; i++) {
thisSumRight+=nums[i];
if(thisSumRight>maxRight) {
maxRight = thisSumRight;
}
}
return getMax(maxL, maxR, maxLeft+maxRight);
}
public static long getMax(long a, long b, long c) {
if (a < b) {
a = b;
}
if (a < c) {
a = c;
}
return a;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
long[] nums = new long[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = in.nextInt();
}
System.out.println(maxSub(nums, 0, nums.length-1));
}
}
但是......Java使用O(nlogn)其他语言应该可以过好像有两组数字还是超时的,所以还是使用一手动态规划:
坑点:别忘了相加超出int的情况
package pta;
import java.util.Scanner;
public class PTA7_1最大子列和问题 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int K = in.nextInt();
int[] nums = new int[K];
for (int i = 0; i < nums.length; i++) {
nums[i] = in.nextInt();
}
long thisSum = 0;
long maxSum = 0;
for (int i = 0; i < nums.length; i++) {
thisSum+=nums[i];
if(thisSum>maxSum) {
maxSum = thisSum;
}
if(thisSum<0) {
thisSum = 0;
}
}
System.out.println(maxSum);
}
}