UVa 1400(LA 3938)動態最大連續和

2021-07-08 15:07:43 字數 1794 閱讀 1236

【題目鏈結】

【解題報告】

劉汝佳的《訓練指南》裡,我覺得這道題目講的不夠詳細(並且書上貌似有一點印刷錯誤?)。

在網上找了很多題解,不過覺得**寫的很醜。直到我看到了這篇題解,覺得**寫的非常漂亮,就虛心學習了。

《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...