首先,先看题.....(虽然比较简单
3027 线段覆盖 2
时间限制: 1 s
空间限制: 128000 KB
题目描述 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
数据范围及提示
数据范围
对于40%的数据,n≤10;
对于100%的数据,n≤1000;
0<=ai,bi<=1000000
0<=ci<=1000000
下面,呈上AC代码,外加详细解析:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 5 using namespace std; 6 7 const int maxn = 1003; 8 9 struct Line{ 10 int start; 11 int end; 12 int value; 13 }l[maxn]; 14 //确定一个结构体,用结构体定义数组,让其里面存储线段的起点、终点与线段长度 15 16 int dp[maxn];//此数组储存关于n条线段的最大价值 17 18 int cmp(const Line &a ,const Line &b)//用来sort排序 19 { 20 return a.end < b.end;//从小到大排序 返回终点较小的 21 } 22 int main() 23 { 24 int n; 25 scanf("%d",&n); 26 for(int i = 1; i <= n; i++) 27 { 28 int a,b,c;//a,b,c分别为线段起点、终点及长度 29 scanf("%d%d%d", &a, &b, &c); 30 l[i].start = a; 31 l[i].end = b; 32 l[i].value = c; 33 //将每条线段的起点、终点、长度储存进去 34 } 35 sort (l+1, l+n+1,cmp);//将l数组进行从小到大排序(按照左端点进行升序排序) 36 //l为地址,+1、+n+1为数组下标,注意左闭右开 37 for(int i = 1; i <= n; i++) 38 { 39 dp[i] = max (dp[i-1], l[i].value);//首先先进行第一次更新 40 for(int p = i - 1; p >= 1; p--) 41 { 42 if (l[p].end <= l[i].start)//p表示在i左边的那条线段,注意这是一个开区间,所以是"<=" 43 dp[i] = max (dp[i], dp[p] + l[i].value);//进行第二次更新 44 } 45 } 46 printf("%d",dp[n]);//输出dp[n] 47 return 0; 48 }