問題描述
輸入一組整數,求出這組數字子串行和中最大值。也就是只要求出最大子串行的和,不必求出最大的那個序列。例如:
序列:-2 11 -4 13 -5 -2,則最大子串行和為20。
複雜度為o(n^2)的演算法
#include #include int maxsubseqsum(const int *a, int n, int *start, int *end)}}
return max_sum;
}int main()
; int start_index, end_index;
int max = maxsubseqsum(a,sizeof(a)/sizeof(a[0]),&start_index,&end_index);
printf("maxsubseqsum is %d -- %d \n",a[start_index],a[end_index]);
printf("max:%d \n",max);
}
演算法度為o(nlogn)的演算法
採用的是「分治「(divide-and-conquer)策略。思想是把問題分成兩個大致相當的子問題,然後遞迴地對他們求解,這是」分「。」治「階段將兩個子問題的解合併到一起,可能再做一些附加的工作,最終得到整個問題的解。
上述問題,把序列分為兩部分,最大子串行可能出現在左半部分,或者右半部分,或者是兩者之間。兩者之間的情況下,先對左半部分求以最後乙個數字為結尾的最大序列和。然後對右半部分以第乙個數字開始算最大序列和,將兩者加起來即是。
int max_3(int a, int b, int c)
int maxsubseqsum2(const int *a, int left, int right)
center = (left + right) / 2;
maxleftsum = maxsubseqsum2(a,left,center);
maxrightsum = maxsubseqsum2(a,center + 1,right);
maxleftbordersum = 0;
leftbordersum = 0;
for(i = center; i >= left; i--)
maxrightbordersum = 0;
rightbordersum = 0;
for(i = center + 1; i <= right; i++)
maxsum = max_3(maxleftsum, maxrightsum, maxleftbordersum + maxrightbordersum);
return maxsum;
}
演算法複雜度為o(n)的演算法
/* 如果a[i]為負數,那麼它不可能代表最優序列的起點,因為任何包含a[i]的作為起點的子串行都可以通過
用a[i+1]作為起點而得到改進。同理,任何小於零的子串行不可能是最優子串行的字首。*/
int maxsubseqsum3(const int *a, int n, int *start, int *end)
else if(cur_sum < 0)
if(j <= *end)
*start = j;
}return max_sum;
}int main()
; int start_index, end_index;
int max = maxsubseqsum3(a,sizeof(a)/sizeof(a[0]),&start_index,&end_index);
printf("maxsubseqsum is %d -- %d \n",a[start_index],a[end_index]);
printf("max:%d \n",max);
}
參考:
最大子串行問題
現在我們將敘述兩個演算法來求解最大子串行和問題 include int maxsubsequencesum int a,int n int main printf max d maxsubsequencesum a,15 return0 int maxsubsequencesum int a 15 ...
最大子串行問題
題目 給定乙個整數列 可能有負數 求該整數列每個子串行的和的最大值,如果都為負數則結果為0 例如 對於輸入 2,11,4,13,5,2 答案為20 從11 到 13,即就是 11 4 13 20 粗略 如下 已測試通過 include using namespace std arr 目標陣列,len...
最大子串行之和問題
最大子串行之和問題 這個問題非常有趣,因為有很多中演算法可以解決這個問題。而這些演算法的執行效率也多種多樣。下面我們將看到四種演算法,演算法複雜度從指數一直過渡到線性複雜度。充分體現了演算法的優劣對執行效率的影響。第一種 intmaxsubsum1 const vector a return max...