T187484 做题时间安排
题目:
题目描述
OIers事先定好了题目需要的起始时间和中止时间。我们要接受一些而拒绝其他的题目,目标是使OIer练习的时间最长。假设在某一时刻一个题目结束,另一个题目就可以立即开始。
输入格式
第一行为一个整数 N N N, N < = 5000 N<=5000 N<=5000,表示题目的数目。
以下N行每行包含两个整数p,k,1<=p
输出格式
OIers最大可能的做题时间。
输入输出样例:
样例输入:
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
样例输出
16
思路:
个人认为本体还是较为简单的一道题。实际上就是一道01背包的模板并进行了一些些修改。先放上状态转移方程:
f
[
j
]
=
m
a
x
(
f
[
w
[
i
]
.
b
e
g
i
n
]
+
w
[
i
]
.
e
n
d
−
w
[
i
]
.
b
e
g
i
n
,
f
[
j
]
)
;
f[ \ j \ ] = max( \ f[ \ w[\ i \ ].begin \ ] + w[ \ i \ ].end - w[ \ i \ ].begin,f[ \ j \ ] \ );
f[ j ]=max( f[ w[ i ].begin ]+w[ i ].end−w[ i ].begin,f[ j ] );
意思就是放入背包和不放入背包的取max。是不是
s
o
e
a
s
y
?
so \ easy?
so easy?
放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int f[1000005],n,m=-1;
struct node{
int begin;
int end;
}w[5010];//存储begin时间与end时间
bool cmp(node a,node b){
return(a.end<b.end)||((a.end==b.end)&&(a.begin<b.begin));
}//以末尾时间排序,否则以开头时间排序
signed main(){
cin>>n;
for (int i=1;i<=n;i++)
cin>>w[i].begin>>w[i].end;
sort(w+1,w+n+1,cmp);
for (int i=1;i<=n;i++)
for (int j=w[n].end;j>=w[i].end;j--)
if (j>=w[i].end)
f[j]=max(f[w[i].begin]+w[i].end-w[i].begin,f[j]);//放入背包与不放入背包取max
cout<<f[w[n].end]<<endl;
return 0;
}
原题:NFLSOJ 5722