找出数组中连续子序列的元素和的最大值。
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;
}