CODEVS 3027 线段覆盖2

首先,先看题.....(虽然比较简单

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 }

猜你喜欢

转载自www.cnblogs.com/New-ljx/p/10343913.html