工作
工作 \operatorname{工作} 工作
题目链接: SSL 1326 \operatorname{SSL\ 1326} SSL 1326
题目
这次故事的主角是 HG !转眼 4 4 4 年过去了, HG 本科毕业了,于是找了份工作。每天 HG 会收到一份任务清单,清单上列出了 n n n 个可能需要他完成的任务。每个任务包含 3 3 3 个信息: T i T_i Ti 、 A i A_i Ai 、 B i B_i Bi , T i T_i Ti 表示完成此任务需要的时间, A i A_i Ai 表示此任务的到达时间, B i B_i Bi 表示此任务的最晚完成时间。在某一时刻若 HG 手上没有任务,那么他可以选择一个已经到达且还能够在 B i B_i Bi 时刻之前(或者恰好在 B i B_i Bi 时刻)完成的任务来做。
由于 HG 有点懒(纯属虚构:D),他想尽量少的减少他的总工作时间,但是他不能在可以做任务的时候故意不做(这样会被炒鱿鱼的>_<),那么他该如何挑选任务来做呢?
你的任务就是求出 HG 的最少工作时间(即总共有多少时间 HG 在做任务)。
输入
第一行一个整数
n
n
n 表示任务数。
以下
n
n
n 行,每行三个整数
T
i
,
A
i
,
B
i
T_i,A_i,B_i
Ti,Ai,Bi 。(
n
<
=
1000
n<=1000
n<=1000 ,
0
<
=
A
i
,
B
i
<
=
1500
0<=A_i,B_i<=1500
0<=Ai,Bi<=1500 ,
T
i
>
=
1
T_i>=1
Ti>=1 )
输出
输出仅一个数,即最少工作时间。
样例输入
3
15 0 25
50 0 90
45 15 70
样例输出
50
数据范围
T
i
>
=
1
T_i>=1
Ti>=1 ,
0
<
=
A
i
,
B
i
<
=
1200
0<=A_i,B_i<=1200
0<=Ai,Bi<=1200 ;
30
%
30\%
30% 的数据满足
n
<
=
5
n<=5
n<=5 ;
60
%
60\%
60% 的数据满足
n
<
=
500
n<=500
n<=500 ;
100
%
100\%
100% 的数据满足
n
<
=
1000
n<=1000
n<=1000 。
输入数据保证
B
i
−
A
i
B_i-A_i
Bi−Ai 要大于等于
T
i
T_i
Ti ,且小于
2
T
i
2T_i
2Ti 。
思路
这道题是一道 dp 。
就设
f
[
i
]
f[i]
f[i] 为到时间
i
i
i 最少工作多久(一定要把工作做完)。
就枚举
i
i
i 为时间,再枚举工作
j
j
j ,如果这个工作可以在
i
i
i 的时候开始并做完,就
f
[
i
+
t
[
j
]
]
=
m
i
n
(
f
[
i
+
t
[
j
]
,
f
[
i
]
+
t
[
j
]
)
f[i + t[j]] = min(f[i + t[j], f[i] + t[j])
f[i+t[j]]=min(f[i+t[j],f[i]+t[j]) 。
(
t
[
j
]
t[j]
t[j] 为这份工作需要的时间)
如果这个时间莫得工作,就从 f [ i − 1 ] f[i - 1] f[i−1] 转移过来。
最后输出 f [ t ] f[t] f[t] , t t t 为最后一份工作完成的时间。
代码
#include<cstdio>
#include<iostream>
using namespace std;
int n, t[2001], a[2001], b[2001], f[2001], s = 2147483647, ss = -2147483647;
bool tt;
int main() {
scanf("%d", &n);//读入
for (int i = 1; i <= n; i++) {
scanf("%d %d %d", &t[i], &a[i], &b[i]);
s = min(s, a[i]);//找出边界
ss = max(ss, b[i]);
}
for (int i = s; i <= ss; i++)
f[i] = 2147483647;//初始化
f[s] = 0;
for (int i = s; i <= ss; i++) {//枚举时间
if(f[i] != 2147483647) {
tt = 1;
for (int j = 1; j <= n; j++) {//枚举工作
if (a[j] <= i && i + t[j] <= b[j]) {//这个工作可以在这个时间完成
tt = 0;
f[i + t[j]] = min(f[i + t[j]], t[j] + f[i]);//dp转移
}
}
if(tt) f[i + 1] = min(f[i + 1], f[i]);//没事干
}
}
printf("%d", f[ss]);//输出
return 0;
}