【DP】ssl 1212大厅安排

Description

有一个演讲大厅需要GEORGE管理,演讲者们事先定好了需要演讲的起始时间和中止时间。GEORGE想让演讲大厅得到最大可能的使用。我们要接受一些预定而拒绝其他的预定,目标自然是使演讲者使用大厅的时间最长。为方便起见,假设在某一时刻一个演讲结束,另一个演讲就可以立即开始。
  计算演讲大厅最大可能的使用时间。

Input

第一行为一个整数n,n <= 100,表示申请的数目。

Output

一个整数,表示大厅最大可能的使用时间。

Sample 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

Sample Output

16

思路

设 f [ i ] 为 以 i 这 个 时 间 点 结 束 所 使 用 的 最 大 时 间 设f[i]为以i这个时间点结束所使用的最大时间 f[i]i使
动态转移方程:
f [ i ] = m a x ( f [ i ] , f [ t [ j ] [ 1 ] ] + t [ j ] [ 2 ] − t [ j ] [ 1 ] ) f[i]=max(f[i],f[t[j][1]]+t[j][2]-t[j][1]) f[i]=max(f[i],f[t[j][1]]+t[j][2]t[j][1])
t [ i ] [ 1 ] 表 示 第 i 个 人 表 演 的 开 始 时 间 , t [ i ] [ 2 ] 表 示 第 i 个 人 表 演 的 结 束 时 间 t[i][1]表示第i个人表演的开始时间,t[i][2]表示第i个人表演的结束时间 t[i][1]it[i][2]i

代码

#include
#include
using namespace std;
int n,t[105][4],f[10005],sum;
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	 scanf("%d%d",&t[i][1],&t[i][2]);
	for (int i=1;i<n;i++)
	 for (int j=i+1;j<=n;j++)
	  {
	  	if (t[i][2]>t[j][2]) swap(t[i][1],t[j][1]),swap(t[i][2],t[j][2]);
	  	 else if(t[i][2]==t[j][2]) {
	  	 	if (t[i][1]>t[j][1]) 
	  	 	 swap(t[i][1],t[j][1]),swap(t[i][2],t[j][2]);
	  	 }
	  }//将时间以结束时间为标准排序,若一样则以开始时间排序。
	sum=t[n][2];//求出最后一个人的结束时间
	for (int i=1;i<=n;i++)//第i个人
	  for (int j=t[i][2];j<=sum;j++)//枚举时间
	     f[j]=max(f[j],f[t[i][1]]+t[i][2]-t[i][1]);//动态转移方程
	printf("%d",f[sum]);
}

其实代码中的选排可以用快排,而且用快排更快点,但是我懒得打,你们可以试一下。

你可能感兴趣的:(DP)