最大子序列,一开始我是用比较方便的向量的:
这样把上面的分治方法再写一次:
理论上是没有错的
#include <string>
#include <iostream>
#include <vector>
#include<climits>
using namespace std;
vector<int> f_m_c_s(vector<int> &a,int low,int mid,int high){
int left_sum=INT_MIN;
int sum=0;
int max_left;
for(int i=mid-1;i!=low-1;--i){
sum=sum+a[i];
if(sum>left_sum){
left_sum=sum;
max_left=i;}}
int right_sum=INT_MIN;
sum=0;
int max_right;
for(int j=mid;j!=high;++j){
sum=sum+a[j];
if(sum>right_sum){
right_sum=sum;
max_right=j;}}
return vector<int>{max_left,max_right,left_sum+right_sum};}
vector<int> f_m_s(vector<int> a,int low,int high){
if(high==low+1){return vector<int>{low,high,a[low]};}
else{int mid=(low+high)/2;
vector<int>a1 = f_m_s(a,low,mid);
int left_low=a1[0],left_high=a1[1],left_sum=a1[2];
//cout<<"low=";
//for(auto i:a1){cout<<i<<" ";}
//cout<<'\n'<<endl;
vector<int>a2=f_m_s(a,mid,high);
int right_low=a2[0],right_high=a2[1],right_sum=a2[2];
//cout<<"high=";
//for(auto i:a2){cout<<i<<" ";}
//cout<<'\n'<<endl;
vector<int>a3=f_m_c_s(a,low,mid,high);
int cross_low=a3[0],cross_high=a3[1];
int cross_sum=a3[2];
//cout<<"cross=";
//for(auto i:a3){cout<<i<<" ";}
//cout<<'\n'<<endl;
if(left_sum>=right_sum && left_sum>=cross_sum){
return a1;}
else if(right_sum>=left_sum && right_sum>=cross_sum){
return a2;}
else {return a3;}}}
但是格式十分麻烦,看了网上的答案之后,发现可以定义一个类,专门用来储存三个数字。
实现:
typedef struct{
unsigned left; unsigned right; unsigned sum;} ma;
这样把上面的分治方法再写一次:
ma f_m_c_s_ma(int a[], unsigned low, unsigned mid, unsigned high){
ma result;
int left_sum=INT_MIN;
int sum=0;
for(int i=mid-1;i!=low-1;--i){
sum=sum+a[i];
if(sum>left_sum){
left_sum=sum;
result.left=i;}}
int right_sum=INT_MIN;
sum=0;
for(int j=mid;j!=high;++j){
sum=sum+a[j];
if(sum>right_sum){
right_sum=sum;
result.right=j;}}
result.sum=left_sum+right_sum;
return result;}
ma f_m_s_ma(int a[],unsigned low,unsigned high){
if(high==low+1){
ma result={low,high,a[low]};
return result;}
else{
int mid=(low+high)/2;
ma left=f_m_s_ma(a,low,mid);
ma right=f_m_s_ma(a,mid,high);
ma cross=f_m_c_s_ma(a,low,mid,high);
if(left.sum>=right.sum && left.sum>=cross.sum){
return left;}
else if(right.sum>=left.sum && right.sum>=cross.sum){
return right;}
else {return cross;}}}
理论上是没有错的