嘛。。。一道dp題,相比貪心的線段覆蓋1,這道題又難了一點。。。題目描述 description
數軸上有n條線段,線段的兩端都是整數座標,座標範圍在0~1000000,每條線段有乙個價值,請從n條線段中挑出若干條線段,使得這些線段兩兩不覆蓋(端點可以重合)且線段價值之和最大。
n<=1000
輸入描述 input description
第一行乙個整數n,表示有多少條線段。
接下來n行每行三個整數, ai bi ci,分別代表第i條線段的左端點ai,右端點bi(保證左端點《右端點)和價值ci。
輸出描述 output description
輸出能夠獲得的最大價值
樣例輸入 sample input
31 2 1
2 3 2
1 3 4
樣例輸出 sample output
4
不過思路都很相似,我們先把讀入的線段按右端點從小到大排序,為什麼要這樣做下面解釋。
之後定義狀態,dp[i]表示前i個區間,選第i個區間的最大值,那麼很容易得出狀態轉移方程dp[i]=max+w[i]。
接下來我們來分析為什麼要排序,因為要獲得最大值,我們需要區間盡量的小,以容納更多的區間,就需要以區間的右端點排序。那麼程式顯而易見了,先列舉i,之後列舉前i-1個區間即可。
1 #include2 #include3 #include4 #include5using
namespace
std;
6const
int maxn=1010;7
struct
line
8a[maxn];
11int
n;12
int dp[maxn];//
前i個區間,選上i的最大價值
13bool
cmp(line a,line b)
1417
void
read()
1824 sort(a+1,a+n+1
,cmp);25}
26int ans=-1;27
void
work()
2838
}39 ans=max(ans,dp[i]);40}
41 cout<43int
main()
44
3027 線段覆蓋 2
剛開始我寫這道題目,我的狀態轉移方程式是 dp i i dp i k dp k 1 j 後來才發現 測試資料太大,會導致超時。接著我又重新梳理了解題的思想,直接遍歷一邊可以多選的選項,然後接著用乙個max值儲存最大的價值,題目便ac了 先貼出我錯誤的 include using namespace ...
3027 線段覆蓋 2
題目描述 description 數軸上有n條線段,線段的兩端都是整數座標,座標範圍在0 1000000,每條線段有乙個價值,請從n條線段中挑出若干條線段,使得這些線段兩兩不覆蓋 端點可以重合 且線段價值之和最大。n 1000 輸入描述 input description 第一行乙個整數n,表示有多...
wikioi 3027 線段覆蓋 2
數軸上有n條線段,線段的兩端都是整數座標,座標範圍在0 1000000,每條線段有乙個價值,請從n條線段中挑出若干條線段,使得這些線段兩兩不覆蓋 端點可以重合 且線段價值之和最大。n 1000 第一行乙個整數n,表示有多少條線段。接下來n行每行三個整數,ai bi ci,分別代表第i條線段的左端點a...