C++学习(1):最大子段和(多种解法)
问题:给定由n个数(可能为负数)组成的序列a1,a2,a3,...,an,求该序列子段和的最大值。
第一种解法:(最容易考虑的方法,将所有的子段一一相加,然后比较)
1 #include<iostream> 2 using namespace std; 3 int Maxsum(int n,int *a,int &besti,int &bestj) 4 { 5 int sum = 0; 6 for(int i=1;i<=n;i++) 7 { 8 int thissum = 0; 9 for(int j=i;j<=n;j++) 10 { 11 thissum +=a[j]; 12 if(thissum>sum) 13 { 14 sum = thissum; 15 besti = i; 16 bestj = j; 17 } 18 } 19 } 20 return sum; 21 } 22 23 int main() 24 { 25 int Case = 1; 26 int T;//共有多少组数 27 cin>>T; 28 while(T>0) 29 { 30 T--; 31 int sum; 32 int N = 9;//一组有多少个数据 33 cin>>N; 34 int* array = new int[N+1]; 35 for(int i=1;i<=N;i++) 36 { 37 cin>>array[i]; 38 } 39 int besti,bestj; 40 sum = Maxsum(N,array,besti,bestj); 41 cout<<"Case "<<Case<<":"<<endl; 42 cout<<sum<<" "<<besti<<" "<<bestj<<endl; 43 44 if(T>0) 45 { 46 cout<<endl; 47 } 48 Case++; 49 } 50 return 0; 51 }
第二种解法:(利用分治算法,将序列从中间分为两个部分a[1:n/2]和a[n\2+1:n],分别求最大子段和,然后比较。)
1 #include<iostream> 2 using namespace std; 3 int MaxSubSum(int *a,int left,int right,int &besti,int &bestj) 4 { 5 int sum = 0; 6 if(left==right) 7 { 8 sum = a[left]; 9 besti = bestj = left; 10 } 11 else 12 { 13 int center = (left+right)/2; 14 int leftsum = MaxSubSum(a,left,center,besti,bestj); 15 int rightsum = MaxSubSum(a,center+1,right,besti,bestj); 16 17 int s1 = -10001; 18 int lefts = 0; 19 for(int i = center;i>=left;i--) 20 { 21 lefts +=a[i]; 22 if(lefts>=s1) 23 { 24 s1 = lefts; 25 besti = i; 26 27 } 28 } 29 30 int s2 = -10001; 31 int rights = 0; 32 for(int j = center+1;j<=right;j++) 33 { 34 rights +=a[j]; 35 if(rights>s2) 36 { 37 s2 = rights; 38 bestj = j; 39 } 40 } 41 42 sum = s1+s2; 43 44 if(sum<leftsum) 45 { 46 sum = MaxSubSum(a,left,center,besti,bestj); 47 } 48 if(sum<rightsum) 49 { 50 sum = MaxSubSum(a,center+1,right,besti,bestj); 51 } 52 } 53 return sum; 54 } 55 56 int MaxSum(int n,int *a,int &besti,int &bestj) 57 { 58 return MaxSubSum(a,1,n,besti,bestj); 59 } 60 61 int main() 62 { 63 int Case = 1; 64 int T;//共有多少组数 65 cin>>T; 66 while(T>0) 67 { 68 bool flag = true; 69 T--; 70 int sum; 71 int N;//一组有多少个数据 72 cin>>N; 73 int* array = new int[N+1]; 74 for(int i=1;i<=N;i++) 75 { 76 cin>>array[i]; 77 } 78 int besti,bestj; 79 //判断是否全部为负数 80 for(int j = 1;j<=N;j++) 81 { 82 if(array[j]>0) flag = false; 83 } 84 if(!flag) 85 { 86 sum = MaxSum(N,array,besti,bestj); 87 cout<<"Case "<<Case<<":"<<endl; 88 cout<<sum<<" "<<besti<<" "<<bestj<<endl; 89 }else 90 { 91 sum = array[1]; 92 besti = bestj = 1; 93 cout<<"Case "<<Case<<":"<<endl; 94 cout<<sum<<" "<<besti<<" "<<bestj<<endl; 95 } 96 97 if(T>0) 98 { 99 cout<<endl; 100 } 101 Case++; 102 } 103 return 0; 104 }