题目描述
某加工厂有 A、B 两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成。由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时由两台机器共同进行加工,所完成任务又会不同。某一天,加工厂接到
n
n
n 个产品加工的任务,每个任务的工作量不尽一样。
你的任务就是:已知每个任务在 A 机器上加工所需的时间
t
1
t_1
t1,B 机器上加工所需的时间
t
2
t_2
t2 及由两台机器共同加工所需的时间
t
3
t_3
t3,请你合理安排任务的调度顺序,使完成所有
n
n
n 个任务的总时间最少。
1
≤
n
≤
6000
1\le n\le 6000
1≤n≤6000,
0
≤
t
1
,
t
2
,
t
3
≤
5
0\le t_1,t_2,t_3\le 5
0≤t1,t2,t3≤5。
算法分析
很简单的思路,设 f [ i ] [ j ] f[i][j] f[i][j] 表示完成前 i i i 个任务 A 机器加工用时为 j j j 时 B 机器的最少加工用时,设计状态转移方程即可。
注意细节,还有使用滚动数组优化时要保存中间变量,开始开的枚举范围开 30000 30000 30000,BZOJ 上能过但是 LG 上 TLE 了,定义了一个 m m m 本机跑 1.2s LG 上居然卡过去了。
代码实现
#include <cstdio>
#include <cstring>
#include <algorithm>
int f[30005];
int main() {
int n;scanf("%d",&n);int m=0;
memset(f,0x7f,sizeof(f));f[0]=0;
for(register int i=1;i<=n;++i) {
int t1,t2,t3;scanf("%d%d%d",&t1,&t2,&t3);
m+=std::max(t1,std::max(t2,t3));
for(register int j=m;j>=0;--j) {
int last=f[j];f[j]=0x3f3f3f3f;
if(t1&&j-t1>=0) f[j]=std::min(f[j],f[j-t1]);
if(t2) f[j]=std::min(f[j],last+t2);
if(t3&&j-t3>=0) f[j]=std::min(f[j],f[j-t3]+t3);
}
}
int ans=0x3f3f3f3f;
for(register int i=0;i<=m;++i) ans=std::min(ans,std::max(i,f[i]));
printf("%d\n",ans);
return 0;
}