首页 > 代码库 > 3027 线段覆盖 2
3027 线段覆盖 2
题目描述 Description
数轴上有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,先按右端点排序,然后判断后面线段line[i]的左端点是不是>=前面线段line[j]的右端点,是就更新dp[i]=max(dp[i],dp[j]+line[i].c);
最后找出最大的dp[]就是答案。。
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 struct node 8 { 9 int a,b,c;10 } line[1005];11 int cmp(node x,node y)12 {13 return x.b<y.b;14 }15 int main()16 {17 int n;18 int dp[1005];19 cin>>n;20 for(int i=0; i<n; i++)21 {22 cin>>line[i].a>>line[i].b>>line[i].c;23 }·24 sort(line,line+n,cmp);25 // for(int i=0; i<n; i++)printf("%d %d %d\n",line[i].a,line[i].b,line[i].c);26 for(int i=0; i<n; i++)27 {28 dp[i]=line[i].c;29 for(int j=0; j<i; j++)30 {31 if(line[j].b<=line[i].a)32 dp[i]=max(dp[i], dp[j]+line[i].c);33 }34 }35 // for(int i=0; i<n; i++)printf("%d ",dp[i]);36 // printf("\n");37 int maxs=0;38 for(int i=0; i<n; i++)39 maxs=max(maxs,dp[i]);40 printf("%d\n",maxs);41 return 0;42 }
3027 线段覆盖 2
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。