【題目鏈結】
【解題報告】
劉汝佳的《訓練指南》裡,我覺得這道題目講的不夠詳細(並且書上貌似有一點印刷錯誤?)。
在網上找了很多題解,不過覺得**寫的很醜。直到我看到了這篇題解,覺得**寫的非常漂亮,就虛心學習了。
《uva - 1400」ray, pass me the dishes!」(線段樹) 》 –miss_minor
這道題目的演算法本身並沒有太多困難的令人感到棘手的地方,雖然是普通的線段樹單點更新,區間查詢,但實現起來,對我來說卻非常有困難。原因在於資料的組織能力實在太弱。而這道題又恰恰由繁複的資料及其相應操作組織而成。
對於線段樹的每個節點(這本身是乙個類)要儲存三個線段資訊(注意這裡又抽象出了乙個類:線段),最大字首,最大字尾,最大子串行。同時還要儲存節點相對應的序列左端點和右端點。
對於每條線段,同樣要儲存左右節點,並且題目中有合併兩條線段的操作,還有需要進行線段「優先順序」的比較。
因此,如何在有限時間內寫出結構清晰,層次完整,便於除錯和擴充套件的**,是十分考驗編碼能力的。
【參考**】
#include
#include
#include
#include
using
namespace
std;
const
int maxn=500000+10;
typedef
long
long ll;
int a[maxn];
long
long s[maxn];
int n,m;
struct segment
segment operator + ( const segment& a )const
bool
operator
< ( const segment& a )const
return l>a.l;
}return vstruct node
};node tree[maxn*4];
void build( int o, int l, int r )
int mid=l+(r-l)/2;
build( o*2, l, mid );
build( o*2+1, mid+1,r );
segment now_left( l,mid,s[mid]-s[l-1] );
segment now_right( mid+1, r, s[r]-s[mid] );
tree[o].max_sub=max( tree[o*2].max_suf+tree[o*2+1].max_pre , max(tree[o*2].max_sub , tree[o*2+1].max_sub) );
tree[o].max_pre=max( tree[o*2].max_pre , now_left+tree[o*2+1].max_pre );
tree[o].max_suf=max( tree[o*2+1].max_suf, now_right+tree[o*2].max_suf );
tree[o].l=tree[o*2].l;
tree[o].r=tree[o*2+1].r;
}node query( int o, int ql, int qr )
}int main( )
build( 1, 1, n );
for( int i=1; i<=m; i++ )
}return
0 ;}
uva 問題 A 最大連續子串行
時間限制 1 sec 記憶體限制 32 mb 給定k個整數的序列,其任意連續子串行可表示為,其中 1 i j k。最大連續子串行是所有連續子串行中元素和最大的乙個,例如給定序列,其最大連續子串行為,最大和為20。現在增加乙個要求,即還需要輸出該子串行的第乙個和最後乙個元素。測試輸入包含若干測試用例,...
最大連續子串行之和(動態規劃)
1.問題描述 設n個元素的序列儲存在陣列a 0.n 1 中,求陣列中連續子串行之和的最大值。2.遞推公式 設all i 為子問題a i.n 1 的連續子串行之和的最大值,start i 為從a i 開始的連續序列之和的最大值,因此 all i a n 1 i n 1時,all i maxi 0,1,...
動態規劃 最大連續子串行乘積
題目描述 給定乙個浮點數序列 可能有正數 0和負數 求出乙個最大的連續子串行乘積。分析 若暴力求解,需要o n 3 時間,太低效,故使用動態規劃。設data i 第i個資料,dp i 以第i個數結尾的連續子串行最大乘積,若題目要求的是最大連續子串行和,則易確定狀態轉移方程為 dp i max dat...