| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
自己做出来的,感觉好开心……附代码和讲解,O(n)的算法……做不出来再看哦改进的关键在于求nFrom的算法。
考虑到其中的状态转化方程:nFrom[i] = max{nFrom[i + 1] , max{Sum[i][k] | i <= k && k < n}};如果要求出所有的Sum[i][k]再比较,必将产生O(n^2)的时间复杂度,而这是不允许的。
如果换一种思路:为什么不直接将maxSum作为一个变量加以研究呢?事实上,如果令Smax[i] = max{Sum[i][k] | i <= k && k < n},那么考虑i-1的情况:
Smax[i - 1] = max{Sum[i - 1][k] | i -1<= k && k < n}
= max{Sum[i - 1][i -1], max {Sum[i-1][k] | i <= k}}
=max{nArray[i-1][i-1], nArray[i-1][i-1] + Smax[i]};
这样一来,问题就迎刃而解了……时间复杂度成功降至O(n)
Here's my Source Code:<C++ Memory: 1336 K Time: 172ms>
#include<iostream>
using namespace std;
const int MAX = 50005;
const int MIN = -2147483647;
static int nArray[MAX] = {0};
//The biggest-sum sequence from a[i]/ to a[i]
static int nFrom[MAX] = {0},nTo[MAX] = {0};
int main(){
int nCount,n,nTempMax,nMax;
scanf("%d",&nCount);
for(;nCount > 0;--nCount){
scanf("%d",&n);
nMax = MIN;
for(int i = 0;i < n;++i){
scanf("%d",&nArray[i]);
}
nTo[0] = nArray[0];
nFrom[n - 1] = nArray[n - 1];
/* Get the nTo[i] */
nTempMax = nArray[0];
for(int i = 1;i < n;++i){
//The highest sum to i is max(highest[i-1],nTempMax(include i)) )
nTempMax = nTempMax > 0 ? nTempMax + nArray[i] : nArray[i];
nTo[i] = nTo[i-1] > nTempMax ? nTo[i-1] : nTempMax;
}
/* Get the nFrom[i] */
nTempMax = nArray[n-1];
for(int i = n - 2;i >= 0;--i){
nTempMax = nTempMax > 0 ? nTempMax + nArray[i] : nArray[i];
nFrom[i] = nFrom[i+1] > nTempMax ? nFrom[i+1] : nTempMax;
}
for(int i = 0;i < n - 1;++i){
nMax = nTo[i] + nFrom[i+1] > nMax ? nTo[i] + nFrom[i+1] : nMax;
}
printf("%d\n",nMax);
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator