标签:
数轴上有n条线段,线段的两端都是整数坐标,坐标范围在0~1000000,每条线段有一个价值,请从n条线段中挑出若干条线段,使得这些线段两两不覆盖(端点可以重合)且线段价值之和最大。
n<=1000
第一行一个整数n,表示有多少条线段。
接下来n行每行三个整数, ai bi ci,分别代表第i条线段的左端点ai,右端点bi(保证左端点<右端点)和价值ci。
输出能够获得的最大价值
3
1 2 1
2 3 2
1 3 4
4
数据范围
对于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 }
标签:
原文地址:http://www.cnblogs.com/ganhang-acm/p/4210864.html