本文主要是介绍P2439 [SDOI2005]阶梯教室设备利用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
快速链接
- 原题链接
- 题目大意
- 输入格式
- 输出格式
- 数据范围
- 解题思路
- 上代码
原题链接
P2439
题目类型: 普 及 + / 提 高 {\color{lightgreen} 普及+/提高} 普及+/提高
AC记录:Accepted
题目大意
读入所有演讲的起始和终止时间,计算最大的可能演讲总时间。
输入格式
第一行包括一个正整数 n n n,为所有的演讲的数目。
以下的 n n n行每行含有两个由空格隔开的整数 p p p和 k k k。这样的一对整数表示一个演讲由时间 p p p开始到时间 k k k结束。
输出格式
输出唯一的一个整数,为最长的演讲总时间。
S a m p l e \mathbf{Sample} Sample I n p u t \mathbf{Input} Input
12
1 2
3 5
0 4
6 8
7 13
4 6
9 10
9 12
11 14
15 19
14 16
18 20
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
16
H i n t & E x p l a i n \mathbf{Hint\&Explain} Hint&Explain
可以选择第 3 3 3个、第 5 5 5个、第 6 6 6个、第 11 11 11个、第 12 12 12个演讲,此时有最长的演讲总时间 16 16 16。
数据范围
对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 1 0 4 , 0 ≤ p < k ≤ 3 × 1 0 4 1≤n≤10^4 ,0\le p<k\le 3\times 10^4 1≤n≤104,0≤p<k≤3×104。
解题思路
d p dp dp,就是 d p dp dp。
我们可以考虑每次添加一个演讲,依次考虑前面所有可以安排当前演讲的状态,取安排当前演讲所获得的价值的最大值,就可以了。
注意:
1.要取所有数里面的最大值。
如果说有一组数据如下:
-------------------
***********************
即
3
1 6
6 19
7 13
如果直接输出 f n f_n fn,则答案为 10 10 10。但是实际上答案为 18 18 18,取的是 f 2 f_2 f2的值。
2.在执行前要先按照开始时间从小到大排序
如果又有一组数据如下:
-------------------
***************
即
3
1 6
7 12
13 18
如果不排序,答案输出的绝对是 10 10 10。而实际上三个时间段都能被选择,则标准答案为 15 15 15。
如果上面的注意事项都做了,那么就大概没什么错误了。状态转移方程如下:
设 f i f_i fi为前 i i i个请求所能得到的最大使用时间, a i , 1 a_{i,1} ai,1为第 i i i个请求的开始时间, a i , 2 a_{i,2} ai,2为第 i i i个请求的结束时间。则有:
当 1 ≤ j < i 且 a i , 1 ≥ a j , 2 时 , 有 f i = max ( f j + a i , 2 − a i , 1 ) 当1\le j<i且a_{i,1}\ge a_{j,2}时,有 f_i=\begin{matrix} \max(f_j+a_{i,2}-a_{i,1}) \end{matrix} 当1≤j<i且ai,1≥aj,2时,有fi=max(fj+ai,2−ai,1)
其中 f i f_i fi的初值为 a i , 2 − a i , 1 a_{i,2}-a_{i,1} ai,2−ai,1。
最后,祝大家早日
上代码
#include<algorithm>
#include<iostream>using namespace std;struct obj{obj(int a=0,int b=0):st(a),ed(b){}int st,ed;
};obj a[10010];
int f[10010];
int n,tar;bool pd(obj x,obj y)
{return x.st<y.st;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin>>n;for(int i=1; i<=n; i++)cin>>a[i].st>>a[i].ed;sort(&a[1],&a[n+1],pd);for(int i=1; i<=n; i++)f[i]=a[i].ed-a[i].st;for(int i=1; i<=n; i++)for(int j=1; j<i; j++)if(a[i].st>=a[j].ed){f[i]=max(f[i],f[j]+a[i].ed-a[i].st);tar=max(tar,f[i]);}
// for(int i=1; i<=n; i++)
// cout<<"f["<<i<<"] = "<<f[i]<<endl;cout<<tar<<endl;return 0;
}
完美切题 ∼ \sim ∼
这篇关于P2439 [SDOI2005]阶梯教室设备利用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!