CodeVS3012 線段覆蓋4(DP 二分)

2021-07-24 10:20:35 字數 834 閱讀 3334

這裡放傳送門

這道題如果是o(

n2) 的dp是比較好想的,用f[i]表示選了前i條線段並且第i條必選的最大價值,每次列舉乙個線段i的時候列舉它前面不和它重疊的線段j,用f[j]+val[i]更新。但是資料範圍這麼大就要考慮優化了。優化這種dp的話比較好想的思路就是省掉內層迴圈。內層迴圈幹的事情有兩個,乙個是找出1..i-1範圍內不和第i條線段重合的線段,二是在這些合法的線段裡面找乙個f最大的來更新f[i]。那麼如果把所有線段按照右端點排序,那麼只要找到了右端點小於i的左端點的最大的那個j,那麼1..j顯然都是符合要求的線段。而我們要查詢的最大值就變成了乙個字首最大值,可以用乙個陣列直接維護。右端點排序以後尋找那個最大的j就可以用二分來解決。時間複雜度o(

nlog

n)。

#include

#include

#include

using

namespace

std;

int n;

long

long f[1000010],v[1000010],tot=0;

struct sega[1000010];

int comp(seg a,seg b)

int divide(int h,int t,int n)

int main()

//以下為原始dp**

/* for (int j=0;jf[i]))

f[i]=f[j]+a[i].c;*/

printf("%lld\n",v[n]);

return

0;}

誒這題好像是我去年noip完了以後做的但是現在才扒拉出來寫題解23333

CODEVS 3012 線段覆蓋 4

題意 每個線段有左端點,右端點和積分,找出互不覆蓋的線段的積分和的最大值。和線段覆蓋2唯一的區別就在於資料範圍變大了,至於它的空間限制縮小對用dp做這個題並沒有什麼影響。先說下線段覆蓋2的做法 按左右端點排序都可以 線段覆蓋4需要按右端點排序,這裡按右端點從小到大排序來講 第一層迴圈從左到右列舉每個...

Codevs 3012 線段覆蓋 4

3012 線段覆蓋 4 時間限制 1 s 空間限制 64000 kb 題目等級 gold 題目描述 description 數軸上有n條線段,線段的兩端都是整數座標,座標範圍在0 1000000,每條線段有乙個價值,請從n條線段中挑出若干條線段,使得這些線段兩兩不覆蓋 端點可以重合 且線段價值之和最...

codevs3012 線段覆蓋4

這個題很好想到它的無後效性,但是我並不是很會寫轉移方程,看了別人的題解以後豁然開朗,序列dp多是以序列的第幾位作為狀態來進行轉移的 include include include using namespace std intn long long ans 1000010 ans i 表示i以前所有...