找出数组中连续子序列的元素和的最大值。

找出数组中连续子序列的元素和的最大值。

int findPathMaxSub(vector<int>&array){

   int len = array.size();

   vector<int>leftMax(len,0);

   vector<int>rightMax(len,0);

 

   for(int i=1;i<len;i++){

       int tempMax = max(array[i-1] + leftMax[i-1],array[i-1]);

       if(tempMax > 0){

           leftMax[i] = tempMax;

       }

    }

 

   for(int i=len-2;i>=0;i--){

       int tempMax = max(array[i+1] + rightMax[i+1],array[i+1]);

       if(tempMax > 0){

           rightMax[i] = tempMax;

       }

    }

 

   int maxNumber = 0x80000000;

   for(int i=0;i<len;i++){

       int temp = array[i]+leftMax[i]+rightMax[i];

       if(temp > maxNumber){

           maxNumber = temp;

       }

    }

   return maxNumber;

}


找出数组中连续子序列的元素和的最大值。

 

来源:http://blog.csdn.net/z_zhangyinqian/article/details/48105237

 

累计遍历算法O(n),效率很高了。

遍历序列的时候对Sum进行累计,如果Sum累积后小于0的话就把Sum重置,每次更新Sum的最大值。最后便能求出最大值。

 

int findPathMaxSub(vector<int>&array){

   int len = array.size();

   int maxNumber = 0x80000000;

   int sum = 0;

   for(int i=0;i<len;i++){

       if(sum<0){

           sum = array[i];

       }

       else

           sum += array[i];

       if(sum > maxNumber){

           maxNumber = sum;

       }

    }

   return maxNumber;

}

 

加了一个记录序列的左右边界

int findPathMaxSub(vector<int>&array){

   int len = array.size();

   int maxNumber = 0x80000000;

   int sum = 0;

   int leftIndex = 0,leftIndexTemp = 0;

   int rightIndex;

   for(int i=0;i<len;i++){

       if(sum<0){

           sum = array[i];

           leftIndexTemp = i;

       }

       else

           sum += array[i];

       if(sum > maxNumber){

           maxNumber = sum;

           leftIndex = leftIndexTemp;

           rightIndex = i;

       }

    }

   return maxNumber;

}

 

还有一个动态规划的思路:

来源:http://blog.csdn.net/z_zhangyinqian/article/details/48105237

 

遍历序列的时候对Sum进行累计,如果Sum累积后小于0的话就把Sum重置,每次更新Sum的最大值。最后便能求出最大值。
其实这个算法就是把序列分为好几块,每一块满足:对于任意k,前k个数的和不会小于0(小于0就没有和后面的数列连续的价值了),当前i个数的和大于最大值时就进行更新,而最大值的左边界就是该块序列的第一个,右边界是第i个。
时间复杂度为O(n),而且可以一边读取一边处理,不需要开数组来存,空间也很省。

#include<cstdio> 

#include<iostream> 

#include<cstring> 

using namespace std; 

const int maxn=100005; 

int main() 

   int t,n; 

   while(scanf("%d",&n)&&n!=0) 

   { 

       int max=-1111111,b=-111111; 

       for(int i=1;i<=n;i++) 

       { 

           scanf("%d",&t); 

           if(b<0) b=t; 

           else 

           { 

                b+=t; 

           } 

           if(b>max) 

              max=b; 

       } 

       printf("%d\n",max); 

   } 

}  


数组的连续子数组最大和(首尾不相连)并给出两个左右边界。

题目来源ACM

题目描述

Given a sequence a[1],a[2],a[3]......a[n],your job is to calculate the max sum of a sub-sequence. For example, given(6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. 

输入描述:

The first line of the input contains aninteger T(1<=T<=20) which means the number of test cases. Then T linesfollow, each line starts with a number N(1<=N<=100000), then N integersfollowed(all the integers are between -1000 and 1000).

      

 

输出描述:

For each test case, you should output twolines. The first line is "Case #:", # means the number of the testcase. The second line contains three integers, the Max Sum in the sequence, thestart position of the sub-sequence, the end position of the sub-sequence. Ifthere are more than one result, output the first one. Output a blank linebetween two cases.

      

 

输入例子:

2

5 6 -1 5 4 -7

7 0 6 -1 1 -6 7 -5

 

输出例子:

Case 1:

14 1 4

 

Case 2:

7 1 6

 

 

#include <iostream>

#include <vector>

#include <algorithm>

 

using namespace std;

 

void findPathMaxSub(vector<int>&array, int times, int num){

   int len = array.size();

   vector<int>leftMax(len,0);

   vector<int>rightMax(len,0);

 

   vector<int>leftIndex(len,0);

   vector<int>rightIndex(len,len-1);

 

   for(int i=1;i<len;i++){

       int tempMax = max(array[i-1] + leftMax[i-1],array[i-1]);

       if(tempMax > 0){ //这里取不取等对最后结果没有影响

           leftMax[i] = tempMax;

           if(array[i-1] == tempMax){

               leftIndex[i] = i-1;

           }

           else

                leftIndex[i] = leftIndex[i-1];

       }

       else

           leftIndex[i] = i;

    }

 

   for(int i=len-2;i>=0;i--){

       int tempMax = max(array[i+1] + rightMax[i+1],array[i+1]);

       if(tempMax > 0){ //这里取不取等对最后结果没有影响

           rightMax[i] = tempMax;

           if(array[i+1] == tempMax){

                rightIndex[i] = i+1;

           }

           else

                rightIndex[i] =rightIndex[i+1];

       }

       else

           rightIndex[i] = i;

    }

 

   int maxNumber = 0x80000000;

   int index = -1;

   for(int i=0;i<len;i++){

       int temp = array[i]+leftMax[i]+rightMax[i];

       if(temp > maxNumber){

           maxNumber = temp;

           index = i;

       }

    }

   cout<<"Case"<<times+1<<":"<<endl;

   cout<<maxNumber<<""<<leftIndex[index]+1<<""<<rightIndex[index]+1<<endl;

   if(times != num){

       cout<<endl;

    }

}

 

int main()

{

   int num;

   cin>>num;

   for(int i=0;i<num;i++){

       int arraySize;

       cin>>arraySize;

       vector<int>array;

       for(int j=0;j<arraySize;j++){

           int temp;

           cin>>temp;

           array.push_back(temp);

       }

       findPathMaxSub(array,i,num-1);

    }

   return 0;

}

 

一个稍微简单一点的思路:

#include <iostream>

#include <vector>

#include <algorithm>

 

using namespace std;

 

void findPathMaxSub(vector<int>&array,int times, int num){

   int len = array.size();

   int maxNumber = 0x80000000;

   int sum = 0;

   int leftIndex = 0,leftIndexTemp = 0;

   int rightIndex;

   for(int i=0;i<len;i++){

       if(sum<0){

           sum = array[i];

           leftIndexTemp = i;

       }

       else

           sum += array[i];

       if(sum > maxNumber){

           maxNumber = sum;

           leftIndex = leftIndexTemp;

           rightIndex = i;

       }

    }

   cout<<"Case"<<times+1<<":"<<endl;

   cout<<maxNumber<<""<<leftIndex+1<<" "<<rightIndex+1<<endl;

   if(times != num){

       cout<<endl;

    }

}

 

int main()

{

   int num;

   cin>>num;

   for(int i=0;i<num;i++){

       int arraySize;

       cin>>arraySize;

       vector<int>array;

       for(int j=0;j<arraySize;j++){

           int temp;

           cin>>temp;

           array.push_back(temp);

       }

       findPathMaxSub(array,i,num-1);

    }

   return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值