【HNOI 2001】产品加工

题目描述

某加工厂有 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 1n6000 0 ≤ t 1 , t 2 , t 3 ≤ 5 0\le t_1,t_2,t_3\le 5 0t1,t2,t35

算法分析

很简单的思路,设 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 
#include 
#include 
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;
}

你可能感兴趣的:(背包DP)