P2224 [HNOI2001]产品加工
Description
A
,
B
A, B
A,B 两台机器,
N
N
N 个任务。
给出每个任务由A做的耗时
t
1
t_1
t1,由B做的耗时
t
2
t_2
t2,AB一起做的耗时
t
3
t_3
t3。
求最小总完成时间。
Solution
想了好久也没有正确的思路。。。
最初想法:
f
[
i
]
[
1
,
2
,
3
]
f[i][1,2,3]
f[i][1,2,3] 表示第
i
i
i 个任务采取
1
/
2
/
3
1/2/3
1/2/3 方案的耗时。
\quad\quad\quad\quad
然额。。不好转移状态方程,无法精确地描述两台机器不同的耗时
题解:
因此,我们需要同时表示出
A
,
B
A,B
A,B 两台机器的工作耗时。
设状态
f
[
i
]
[
j
]
f[i][j]
f[i][j] 表示第
i
i
i 个任务,
A
A
A 机器耗时为
j
j
j ——
B
B
B 的最短耗时(为什么取最短是废话吧 )
这样我们以
j
,
f
[
i
]
[
j
]
j, f[i][j]
j,f[i][j] 同时表示
A
,
B
A,B
A,B 耗时(非常新鲜非常美味)
考虑状态转移:
当
t
1
,
t
2
,
t
3
t_1, t_2, t_3
t1,t2,t3 有意义时:
f
[
i
]
[
j
]
=
min
(
f
[
i
−
1
]
[
j
−
t
1
]
,
f
[
i
−
1
]
[
j
]
+
t
2
,
f
[
i
−
1
]
[
j
−
t
3
]
+
t
3
)
f[i][j]=\min(f[i-1][j-t_1], f[i-1][j]+t_2, f[i-1][j-t_3]+t_3)
f[i][j]=min(f[i−1][j−t1],f[i−1][j]+t2,f[i−1][j−t3]+t3)
f
[
i
−
1
]
[
j
−
t
1
]
f[i-1][j-t_1]
f[i−1][j−t1] 表示由
A
A
A 完成
f
[
i
−
1
]
[
j
]
+
t
2
f[i-1][j]+t_2
f[i−1][j]+t2 表示由
B
B
B 完成
f
[
i
−
1
]
[
j
−
t
3
]
+
t
3
f[i-1][j-t_3]+t_3
f[i−1][j−t3]+t3 表示由
A
,
B
A,B
A,B 共同完成
Stuff:倒序枚举除掉一维 / 最后 A , B A,B A,B 时间取较大的
ll n;
ll f[30004], sum=0;
int main(){
n=read();
memset(f, 0x3f, sizeof(f));
f[0]=0;
for(ll o = 1; o <= n ; o++){
ll t1=read(), t2=read(), t3=read();
sum+=max(t1, max(t2, t3));
for(ll j = sum; j >= 0 ; j--){//倒序枚举
ll a=inf, b=inf, c=inf;
if(t2) a=f[j]+t2;
if(t1&&j>=t1) b=f[j-t1];
if(t3&&j>=t3) c=f[j-t3]+t3;
f[j]=min(a, min(b, c));
}
}
ll ans=inf;
for(ll i = 1; i <= sum ; i++) ans=min(ans, max(i, f[i]));//A,B 取时间较大的
printf("%lld", ans);
return 0;
}