首先,這個問題並不複雜,有o(n^2)的字首和做法,還有分治o(nlgn)的做法。
還有o(n)的做法。
o(n)的做法,目前我知道了兩種。
一種就是
sum[i,j] = sj - s(i-1),先計算字首和,然後從左往右記錄當前碰到的最小字首和的下標,因為固定sj,就要使s(i-1)最小。然後在從左往右跑一遍,即可。
這種做法需要計算字首和,和預處理相應的下標。總共多需要兩個陣列。
接下來的一種做法,節約了空間。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef
long
long ll;
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define pii pair
#define all(x) x.begin(),x.end()
#define mem(a,b) memset(a,b,sizeof(a))
#define per(i,a,b) for(int i = a;i <= b;++i)
#define rep(i,a,b) for(int i = a;i >= b;--i)
const
int maxn =
3e5;
int n =
0,m =0;
int a[maxn+10]
;int s[maxn+10]
;int sm[maxn+10]
;//記錄從1-j中最小的s的下標i,s[j] - s[i-1]最大,固定 s[j],相當於使s[i-1]最小
//然後掃瞄一次陣列,維護目前遇到過的最小s
//複雜度o(n)
intmain()
int mins =
0,min_id =0;
sm[1]
=0;per
(i,2
,n)else
}int maxv =
-inf;
per(i,
1,n)
}printf
("%d %d : %d\n"
,l,r,maxv);}
return0;
}
2,設s[i]表示以a[i]結尾的連續子串行的最大和。由於遞推s[i]陣列可以節約為乙個變數即可。
#include
#define per(i,a,b) for(int i = (a);i <= (b);++i)
#define inf 0x3f3f3f3f
using namespace std;
const
int maxn =
3e5;
int a[maxn+10]
;int n =0;
void
solve()
}else}}
printf
("the maximum is %d\nthe internal is %d to %d\n"
,maxv,l,r);}
intmain()
solve()
;}return0;
}
第二種為什麼比第一種方法節約空間。
前者不是增量演算法,後面的演算法通過增量遞推,充分利用了每一步的計算結果。增量,這種xx,在很多方面都有很好的應用,可以是演算法變得高效。
關於求最大連續子串行 和 問題
昨天看到乙個演算法題目,題目是這樣子的 輸入一組整數,求出這組數字子串行和中最大值。也就是只要求出最大子串行的和,不必求出最大的那個序列。例如 序列 2 11 4 13 5 2,則最大子串行和為20。序列 6 2 4 7 5 3 2 1 6 9 10 2,則最大子串行和為16。這個題目也是在csdn...
求最大連續子串行的和
小王的賬本 小王出門打零工,工作很不穩定,收入也很不穩定,他找了乙個賬本記錄他每天的支出,例如 1月1日 收入320 1月2日 沒找到工作,吃飯花了30 1月3日 掙50 1月4日 無工作,吃飯花了17 1月5日 無工作,租房 吃飯花了2600 年底了,小王想知道自己賬本上哪一段時間掙錢掙的最多。剛...
最大連續子串行和
最大連續子串行和問題是個很老的面試題了,最佳的解法是o n 複雜度,當然其中的一些小的地方還是有些值得注意的地方的。這裡還是總結三種常見的解法,重點關注最後一種o n 的解法即可。需要注意的是有些題目中的最大連續子串行和如果為負,則返回0 而本題目中的最大連續子串行和並不返回0,如果是全為負數,則返...