Codevs 3012 線段覆蓋 4

2022-02-13 05:23:08 字數 1746 閱讀 7890

3012 線段覆蓋 4

時間限制: 1 s

空間限制: 64000 kb

題目等級 :** gold

題目描述 description

數軸上有n條線段,線段的兩端都是整數座標,座標範圍在0~1000000,每條線段有乙個價值,請從n條線段中挑出若干條線段,使得這些線段兩兩不覆蓋(端點可以重合)且線段價值之和最大。

輸入描述 input description

第一行乙個整數n,表示有多少條線段。

接下來n行每行三個整數, ai bi ci,分別代表第i條線段的左端點ai,右端點bi(保證左端點《右端點)和價值ci。

輸出描述 output description

輸出能夠獲得的最大價值

樣例輸入 sample input

3 1 2 1

2 3 2

1 3 4

樣例輸出 sample output

4 資料範圍及提示 data size & hint

n <= 1000000

0<=ai,bi<=1000000

0<=ci<=1000000

資料輸出建議使用long long型別(pascal為int64或者qword型別)

分類標籤 tags

二分法 動態規劃 序列型dp

/*

dp.f[i]表示選前i個線段的最優值.

然後dp選不選該線段.

我們保證f值單調.

然後我們從n^2優化到nlogn.

如果從前邊轉移的話.

按照右端點排序.

找乙個合法最近的線段更新.

*/#include

#include

#include

#define maxn 1000001

#define ll long long

using

namespace

std;

ll f[maxn],n,tot;

struct datas[maxn];

ll read()

while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();

return x*f;

}bool cmp(const data &x,const data &y)

return ans;

}int main()

/*

按照左端點排序.

從後面更新狀態.

*/#include

#include

#include

#define maxn 1000001

#define ll long long

using

namespace

std;

ll f[maxn],n,tot;

struct datas[maxn];

ll read()

while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();

return x*f;

}bool cmp(const data &x,const data &y)

return ans;

}int main()

CODEVS 3012 線段覆蓋 4

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

codevs3012 線段覆蓋4

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

CodeVS3012 線段覆蓋4(DP 二分)

這裡放傳送門 這道題如果是o n2 的dp是比較好想的,用f i 表示選了前i條線段並且第i條必選的最大價值,每次列舉乙個線段i的時候列舉它前面不和它重疊的線段j,用f j val i 更新。但是資料範圍這麼大就要考慮優化了。優化這種dp的話比較好想的思路就是省掉內層迴圈。內層迴圈幹的事情有兩個,乙...