/*
* 求数组的最大子段和
*/
package acm;
import static java.lang.System.out;
import java.io.BufferedInputStream;
import java.util.Scanner;
public class Acm1003 {
public int bestStar = 0; // 起始下标
public int bestEnd = 0; // 终止下标
/*动态规划*/
public int MaxSum1(int[] a){
int sum = 0;
int b = 0;
for(int i=0; i<a.length; i++){
if( b>0 ){
b += a[i];
}else{
b = a[i];
}
if( b>sum ) {
sum = b;
}
}
return sum;
}
/*一般算法*/
public int MaxSum2(int[] a){
int sum = 0;
for(int i=0; i<a.length; i++){
for(int j=i; j<a.length; j++){
int thissum = 0;
for(int k=i; k<=j;k++){
thissum += a[k];
}
if(thissum > sum){
sum = thissum;
this.bestStar = i;
this.bestEnd = j;
}
}
}
return sum;
}
/*一般算法的优化*/
public int MaxSum3(int[] a){
int sum = 0;
for(int i=0; i<a.length; i++){ // 可以将 for 判断条件 改为 a[i]>0&&i<a.length 以减少运算量
int thissum = 0;
for(int j=i; j<a.length; j++){
thissum += a[j];
if(thissum > sum){
sum = thissum;
this.bestStar = i;
this.bestEnd = j;
}
}
}
return sum;
}
/*分治算法*/
public int MaxSubSum(int[] a, int left, int right ){
int sum = 0;
if(left == right){
sum = ( a[left]>0 ? a[left] : 0 );
}else{
int center = ( left+right ) / 2;
int leftsum = MaxSubSum(a,left,center);
int rightsum = MaxSubSum(a,center+1,right);
int sL = 0;
int lefts = 0;
for(int i=center; i>=left; i--){
lefts += a[i];
if(lefts>sL) sL=lefts;
}
int sR = 0;
int rights = 0;
for(int i=center+1; i<=right; i++){
rights += a[i];
if(rights>sR) sR=rights;
}
sum = sL + sR;
if(sum<leftsum) sum=leftsum;
if(sum<rightsum) sum=leftsum;
}
return sum;
}
public int MaxSum4(int[] a){
return MaxSubSum(a,0,a.length-1);
}
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int[] a = {-2,11,-4,13,-5,-2};
Acm1003 acm10031 = new Acm1003();
out.println("动态规划 :"+acm10031.MaxSum1(a));
Acm1003 acm10032 = new Acm1003();
out.println("一般算法: "+acm10032.MaxSum2(a)+"\t起始:"+acm10032.bestStar+" 终点 "+acm10032.bestEnd);
Acm1003 acm10033 = new Acm1003();
out.println("一般算法优化: "+acm10033.MaxSum2(a)+"\t起始:"+acm10033.bestStar+" 终点 "+acm10033.bestEnd);
out.println("分治算法:" +acm10033.MaxSum4(a));
}
}
求数组最大子段和的常用算法
最新推荐文章于 2020-10-26 15:45:06 发布