标签:style class blog code java http
1 package digui_fenzhi; 2 3 //最大字段和 4 import java.util.Random; 5 import java.util.Scanner; 6 7 class SimpleAlgorithm//简单算法 8 { 9 int maxSum(int[] a) 10 { 11 int sum=0; 12 for(int i=0;i<a.length;i++) 13 for(int j=i;j<a.length+1;j++) 14 { 15 int thissum=0; 16 for(int k=i;k<j;k++) 17 thissum+=a[k]; 18 if(thissum>sum) 19 { 20 sum=thissum; 21 } 22 } 23 return sum; 24 } 25 } 26 27 class DivideConquer//分治法 28 { 29 private int maxSubSum(int[] a,int left,int right) 30 { 31 int sum=0; 32 int s1=0,s2=0,lefts=0,rights=0; 33 int center,leftsum,rightsum; 34 if(left==right) 35 { 36 if(a[left]>0) 37 sum=a[left]; 38 else 39 sum=0; 40 } 41 else 42 { 43 center=(left+right)/2; //划分 44 leftsum=maxSubSum(a,left,center); //对应情况1,递归求解 45 rightsum=maxSubSum(a,center+1,right); //对应情况2,递归求解 46 //求解s1 47 for(int i=center;i>=left;i--) 48 { 49 lefts=lefts+a[i]; 50 if(lefts>s1) 51 s1=lefts; 52 } 53 //再求解s2 54 for(int j=center+1;j<=right;j++) 55 { 56 rights=rights+a[j]; 57 if(rights>s2) 58 s2=rights; 59 } 60 sum=s1+s2; //计算情况3的最大子段和 61 if(sum<leftsum) 62 sum=leftsum; 63 if(sum<rightsum) 64 sum=rightsum; 65 } 66 return sum; 67 } 68 int maxSum(int[] a) 69 { 70 return maxSubSum(a,0,a.length-1); 71 72 } 73 } 74 75 class DynamicProgramming//动态规划法 76 { 77 int maxSum(int[] a) 78 { 79 int sum=0; 80 int b=0; 81 for(int i=0;i<a.length;i++) 82 { 83 if(b>0) b+=a[i]; 84 else b=a[i]; 85 if(b>sum)sum=b; 86 } 87 return sum; 88 } 89 90 } 91 92 class Optimal{//判断最优算法 93 public void Judge(long time1,long time2,long time3){ 94 long b=time1; 95 if(time1 > time2){ 96 b = time2; 97 } 98 if(b > time3){ 99 b = time3; 100 } 101 if(b==time1){ 102 System.out.println("最优算法是简单算法!"); 103 } 104 else if(b== time2){ 105 System.out.println("最优算法是分治算法!"); 106 } 107 else if(b== time3){ 108 System.out.println("最优算法是动态规划算法!"); 109 } 110 111 } 112 } 113 public class SubSegment { 114 public static void main(String[] args) { 115 System.out.println("请输入整数个数n:"); 116 Scanner in = new Scanner(System.in); 117 int n = in.nextInt(); 118 int a1[]=new int[n+1]; 119 int a2[]=new int[n+1]; 120 int a[]=new int[n+1]; 121 Random random = new Random(); 122 System.out.println("得到的随机数是:"); 123 for(int i=0;i<=n;i++) 124 { 125 a1[i] =(int)Math.floor((random.nextDouble()*10.0)); //产生0-10之间随机数 126 a2[i] =(int)Math.floor((random.nextDouble()*10.0)); //产生0-10之间随机数 127 a[i]=a1[i]-a2[i]; 128 System.out.print(a[i]+" "); 129 } 130 SimpleAlgorithm s = new SimpleAlgorithm(); 131 DivideConquer d = new DivideConquer(); 132 DynamicProgramming p = new DynamicProgramming(); 133 134 long start1= System.currentTimeMillis(); 135 System.out.println(" "); 136 System.out.println("简单算法算得最大字段和为:\n"+s.maxSum(a)); 137 long end =System.currentTimeMillis(); 138 long time = (end - start1); 139 System.out.println("用时:" + time + "毫秒!"); 140 141 long start2 = System.currentTimeMillis(); 142 System.out.println("分治算法算得最大字段和为:\n"+d.maxSum(a)); 143 long end1 =System.currentTimeMillis(); 144 long time1 = (end1 - start2); 145 System.out.println("用时:" + time1 + "毫秒!"); 146 147 long start3 = System.currentTimeMillis(); 148 System.out.println("动态规划算法算得最大字段和为:\n"+p.maxSum(a)); 149 long end2=System.currentTimeMillis(); 150 long time2 = (end2- start3); 151 System.out.println("用时:" + time2 + "毫秒!"); 152 153 Optimal o = new Optimal(); 154 o.Judge(time, time1, time2); 155 156 } 157 158 }
运算结果:
动态规划算法:
该代码从头到尾扫描一次,如果只有一项,则最大子段和是它本身,不管是否为负数还是正数。假设第二项为正数的话,显然最大子段和就是第二项本身了,该怎样解决了呢,这样想,因为这是求连续子段和,倘若该项的前n-1项连续子段和为负数,则最大子段和max就会改变,因为一个数加上一个负数,值会减小。所以当前n-1项连续子段和为负数时,就舍弃这一段,从下一项开始。但注意,最大连续子段和中的元素可以允许有负数的存在,此时就需要设置一个max来保存最大值的情况,如果增加,则更新max的情况,否则不更新。
/* 动态规划法思想:将较大的问题分解成较小的问题,先求解子问题, 然后通过子问题的解得到原问题的解,经过分解的子问题之间并不是 相互独立的。*/
标签:style class blog code java http
原文地址:http://www.cnblogs.com/yijiesuifeng/p/3790593.html