zoukankan      html  css  js  c++  java
  • BZOJ1222: [HNOI2001]产品加工(诡异背包dp)

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 907  Solved: 587
    [Submit][Status][Discuss]

    Description

    某加工厂有A、B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成。由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时由两台机器共同进行加工,所完成任务又会不同。某一天,加工厂接到n个产品加工的任务,每个任务的工作量不尽一样。你的任务就是:已知每个任务在A机器上加工所需的时间t1, B机器上加工所需的时间t2及由两台机器共同加工所需的时间t3,请你合理安排任务的调度顺序,使完成所有n个任务的总时间最少。

    Input

    输入共n+1行第1行为 n。 n是任务总数(1≤n≤6000)第i+1行为3个[0,5]之间的非负整数t1,t2,t3,分别表示第i个任务在A机器上加工、B机器上加工、两台机器共同加工所需要的时间。如果所给的时间t1或t2为0表示任务不能在该台机器上加工,如果t3为0表示任务不能同时由两台机器加工。

    Output

    最少完成时间

    Sample Input

    5
    2 1 0
    0 5 0
    2 4 1
    0 0 3
    2 1 1

    Sample Output

    9

    HINT

     

    Source

    一道非常妙的dp

    刚开始确实一点思路都没有,本来想的是$f[i][3]$分别表示用A,B,C完成的最早时间,但是很明显转移的时候会出错

    正解用了非常神奇的一种dp方法

    考虑到只有两种机器

    $f[i]$表示的是当完成当前所有任务且A机器用了$i$时间时,B机器用的最小的时间

    也就是我们可以去枚举A机器完成任务的时间

    这样的话,对于一个物品来说,

    如果是被$B$完成,那么$f[i]+=timeB$

    如果是被$A$完成,那么$f[i]=min(f[i-timeA],f[i]$

    如果是被$C$完成,那么$f[i]=min(f[i-timeC]+C,f[i]$

    这样最后使得最大值最小就可以了

    #include<cstring>
    #include<cstdio>
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a<b?b:a)
    char buf[1<<21],*p1=buf,*p2=buf;
    //#define int long long 
    using namespace std;
    const int MAXN=5*6001,INF=1e9+10;
    inline int read() {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int f[MAXN];
    int main() {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #endif
        memset(f,0xf,sizeof(f));
        f[0]=0;
        int N=read(),limit=0;
        for(register int i=1;i<=N;i++) {
            int A=read(),B=read(),C=read();
            A = A==0?INF:A;
            B = B==0?INF:B;
            C = C==0?INF:C;
            limit+=min(A,min(B,C));    
            for(register int j=limit;j>=0;j--) {
                B==INF?f[j]=B:f[j]+=B;
                if(j>=A) f[j]=min(f[j-A],f[j]);
                if(j>=C) f[j]=min(f[j-C]+C,f[j]);
            }        
        }
        int ans=INF;
        for(int i=0;i<=limit;i++) ans=min(ans,max(i,f[i]));
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    fn project 试用之后的几个问题的解答
    fn project 扩展
    fn project 生产环境使用
    fn project 对象模型
    fn project AWS Lambda 格式 functions
    fn project 打包Function
    fn project Function files 说明
    fn project hot functions 说明
    fn project k8s 集成
    fn project 私有镜像发布
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8781716.html
Copyright © 2011-2022 走看看