codevs 3027線段覆蓋 2

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


n<=1000


輸入描述 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
數據範圍


對於40%的數據,n≤10;


對於100%的數據,n≤1000;


0<=ai,bi<=1000000


0<=ci<=1000000

也是經典dp吧,這個貪心估計做不出來,首先是按照右端點從小到大排序,然後令f[i]初始值爲線段i的價值(先初始化f[n]在排序會錯,我就是這麼錯了好久的);

dp公式:f[i] = max(f[i],f[j]+p[i].v),(p[i]是第i條線段

最大值: max = max(max,f[i]);

#include<iostream>
#include<algorithm>
using namespace std;
typedef struct mm
{
	int l,r,v;
}m;
int f[1001];
int n;
int maxx = 0;
m p[1001];
bool cmp(const m &s1,const m &s2)
{
	if(s1.r == s2.r)return s1.l < s2.l;
	return s1.r < s2.r;
}
int main()
{
	cin >> n;
	for(int i = 0;i < n;i++)
	{
			cin >> p[i].l >> p[i].r >> p[i].v;
	}	
	sort(p,p+n,cmp);
	for(int i = 0;i < n;i++)
	{
		f[i] = p[i].v;
	}
	for(int i = 1;i < n;i++)
	{
		for(int j = 0;j < i;j++)
		{
			if(p[j].r <= p[i].l)
			{
				f[i] = max(f[i],f[j]+p[i].v);
			}
		}
		maxx = max(f[i],maxx);
	}
	cout << maxx;
	return 0;
 } 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章