zoukankan      html  css  js  c++  java
  • 最大子序列和问题的几种算法

    直接贴代码了:

    package data.structure.chapter2;

    import java.util.Date;
    import java.util.Random;

    public class MaxSequenceSumTest {

    /**
    * @param args
    */
    public static void main(String[] args) {
    int [] array=new int[10000000];
    Random r=new Random(100);
    for(int i=0;i<array.length;i++){
    int k=r.nextInt(20);
    if(k%2==0)
    array[i]=0-k;
    else
    array[i]=k;
    // System.out.print(array[i]+" ");
    }
    // System.out.println();
    // maxSum1(array);
    // maxSum2(array);
    // maxSum3(array);
    long start=System.currentTimeMillis();
    int sum=maxSum4(array,0,array.length-1);
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");

    maxSum5(array);
    }

    /**
    * f(n)=f(n-1)+f(n-2)
    * f(n)=1 n<=1
    */
    public static void f(int n){
    long [] array=new long[n+1];
    array[0]=1;
    array[1]=1;
    array[2]=2;
    for(int i=3;i<n+1;i++){
    array[i]=array[i-1]+array[i-2];
    }
    for(int i=0;i<n+1;i++){
    System.out.println("i="+i+"---------- "+array[i]);
    }
    }

    public static int maxSum1(int [] array){
    long start=System.currentTimeMillis();
    int sum=0;
    for(int i=0;i<array.length;i++){
    for(int j=i+1;j<array.length;j++){
    int s=array[i];
    for(int k=i+1;k<=j;k++){
    s=s+array[k];
    }
    if(s>sum) sum=s;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return sum;
    }

    /**
    * 时间减半而已
    * @param array
    * @return
    */
    public static int maxSum2(int [] array){
    int sum=0;
    long start=System.currentTimeMillis();
    for(int i=0;i<array.length;i++){
    for(int j=i+1;j<array.length;j++){
    if(array[i]<0)
    break;
    int s=array[i];
    for(int k=i+1;k<=j;k++){
    s=s+array[k];
    }
    if(s>sum) sum=s;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return sum;
    }

    /**
    * 少一重循环
    * @param array
    * @return
    */
    public static int maxSum3(int [] array){
    long start=System.currentTimeMillis();
    int sum=0;
    for(int i=0;i<array.length;i++){
    int s=array[i];
    for(int j=i+1;j<array.length;j++){
    s=s+array[j];
    if(s>sum) sum=s;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return sum;
    }


    /**
    * O(NlogN)时间复杂度
    * 分治策略:
    * 分:把问题分成两个大致相等的子问题,然后递归地对他们求解
    * 治:将两个子问题的解修补到一起并可能再做些少量的附加工作,最后得到整个问题的解
    * @param array
    * @param left
    * @param right
    * @return
    */
    public static int maxSum4(int [] array,int left,int right){
    if (left == right)
    if (array[left] > 0)
    return array[left];
    else
    return 0;
    int middle=(left+right)/2;
    int lMax=maxSum4(array,left,middle);
    int rMax=maxSum4(array,middle+1,right);
    int a=0;
    int aMax=0;
    for(int i=middle;i>=left;i--){
    a=a+array[i];
    if(a>aMax)
    aMax=a;
    }
    int b=0;
    int bMax=0;
    for(int i=middle+1;i<right;i++){
    b=b+array[i];
    if(b>bMax)
    bMax=b;
    }
    return Math.max(Math.max(lMax, rMax),aMax+bMax);
    }

    /**
    * 如果a[i]小于零,那么它不可能代表最优序列的起点,因为任何包含a[i]的作为起点的子序列都可以通过
    * 用a[i+1]作为起点而得到改进。同理,任何小于零的子序列不可能是最优子序列的前缀。
    * @param array
    * @return
    */
    public static int maxSum5(int []array){
    long start=System.currentTimeMillis();
    int maxSum=0,thisSum=0;
    for(int i=0;i<array.length;i++){
    thisSum=thisSum+array[i];
    if(thisSum>maxSum){
    maxSum=thisSum;
    }else if(thisSum<0){
    thisSum=0;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+maxSum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return maxSum;
    }

    }

  • 相关阅读:
    多重背包 HDU2191
    带限制求最小价值的完全背包 HDU1114
    均分背包 HDU1171
    经典01背包问题 HDU2602
    记忆化搜索 POJ1579
    最大递增子序列变形——二维带权值 O(n*n) HDU1069
    最大递增子序列变形——二维 O(n*logn) TOJ4701
    OCJP(1Z0-851) 模拟题分析(六)over
    OCJP(1Z0-851) 模拟题分析(八)over
    OCJP(1Z0-851) 模拟题分析(九)over
  • 原文地址:https://www.cnblogs.com/yshb/p/2556965.html
Copyright © 2011-2022 走看看