前言
算法练习记录
题目
最大子段和问题。给定由n个整数组成的序列,求序列中子段的最大和,若所有整数均为负整数时定义最大子段和为0。
例如, 当(a1,a2,a3,a4 ,a5,a6) = (-2,11,-4,13,-5,-2)时,最大子段和为: a2+a3+a4=20
输入格式:
第一行输入整数个数n(1≤n≤10000),再依次输入n个整数。
输出格式:
输出第一行为最大子段和,第二行为子段第一个数和最后一个数在整个序列中的位序。
输入样例1:
6
-2 11 -4 13 -5 -2
输出样例1:
20
2 4
分析
枚举遍历算法。对数组进行k段长度划分,k=1,2,3,…,n-1,每次k段以1为步长向数组末移动,计算每段和,记录和最大值。图示:
k\i | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
1 | -2 | 11 | -4 | 13 | -5 | -2 |
2 | -2 11 | 11 -4 | -4 13 | 13 -5 | -5 -2 | -2 |
3 | -2 11 -4 | 11 -4 13 | -4 13 -5 | 13 -5 -2 | -5 -2 | -2 |
… |
代码(java):
package com.hb;
import java.util.Scanner;
/*
* 最大子段和问题。给定由n个整数组成的序列,求序列中子段的最大和,若所有整数均为负整数时定义最大子段和为0。
例如, 当(a1,a2,a3,a4 ,a5,a6) = (-2,11,-4,13,-5,-2)时,最大子段和为: a2+a3+a4=20
*
* */
public class AlgorithmTest2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n =sc.nextInt();
int num[] = new int[10002];
int maxNum =0;
int x=0;
int y=0;
boolean flag=false;
for(int i=0;i<n;i++)
{ num[i] =sc.nextInt();
if(num[i]>=0)flag=true;
}
for(int i=0;i<n;i++)
for(int j=0;(j+i)<n;j++)
{ int sum =0;
for(int k=i;k<(j+i);k++)
sum+=num[k];
if(sum>maxNum)
{
maxNum = sum;
x = i+1;
y = i+j;
}
}
if(flag) {
System.out.println(maxNum);
System.out.println(x + " " + y);
}
else
System.out.println(0);
}
}