• 20191111luogu2224加工调度 | 背包DP


    luogu2224加工调度

    同时推荐luogu里的第一篇题解

    题意:

    n个物品,可以在A机器上加工花费t1,可以在B机器上加工花费t2,或者A、B同时加工花费t3,

    A、B同时加工物品,求加工所有的物品的最短用时

    神奇的dp:

    因为用背包转移状态,转移后背包是填满的状态 ,

    所以我们不用排序考虑物品选择那种方式加工 ,不用担心同时加工会不会耽误空档时间,不用考虑谁先谁后的问题, 背包的优势在这道题上体现了出来

    f[i][j]表示加工前i个物品A机器加工总时间为j时B的最小时间

    转移方程:

    f[i][j] = min(f[i][j],f[i-1][j-a[i].t1])

    f[i][j]  = min(f[i][j],f[i-1][j]+a[i].t2)

    f[i][j] = min(f[i][j],f[i-1][j-a[i].t3]+a[i].t3)

    细节:

    范围为n《=6000,t 《=5,所以直接开二维数组会MLE,要用滚动数组压掉一维

    在写的时候要先判断第二个状态,再判断剩余两个状态,便于转移

    这样我们又会发现TLE了,考虑优化,由于t《=5,所以前i个物品最大时间就是5*i,于是j从5*i倒叙枚举,就可以解决TLE的问题

    时间复杂度:O(小于n*n*5)

    好题!!!

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 #define minn(x,y) x<y?x:y
     6 #define maxn(x,y) x>y?x:y
     7 #define re register
     8 struct node
     9 {
    10     int t1,t2,t3;
    11 }a[6005];
    12 int f[30005];
    13 inline int read()
    14 {
    15     int res = 0,f = 1;
    16     char c;
    17     c = getchar();
    18     while(c < '0' || c > '9')
    19     {
    20         if(c == '-')f = -1;
    21         c = getchar();
    22     }
    23     while(c >= '0' && c <= '9')
    24     {
    25         res = res * 10 + c - '0';
    26         c = getchar();
    27     }
    28     return res * f;
    29 }
    30 int main()
    31 {
    32     int n,sum = 0;
    33     n = read();
    34     for(re int i = 1;i <= n;i ++)
    35     {
    36         a[i].t1 = read();
    37         a[i].t2 = read();
    38         a[i].t3 = read();
    39         sum = sum + max(a[i].t1,a[i].t3);
    40         
    41     }
    42     for(re int i = 1;i <= sum;i ++)f[i] = 1e9;
    43     for(re int i = 1;i <= n;i ++)
    44     {
    45         for(re int j = 5 * i;j >= 0;j --)
    46         {
    47             if(a[i].t2)f[j] = f[j] + a[i].t2;
    48             else f[j] = 1e9;
    49             if(a[i].t3 && j >= a[i].t3)f[j] = minn(f[j],f[j - a[i].t3] + a[i].t3);
    50             if(a[i].t1 && j >= a[i].t1)f[j] = minn(f[j],f[j - a[i].t1]);
    51         }
    52     }
    53     int ans = 1e9;
    54     for(re int i = 0;i <= sum;i ++)
    55     {
    56         ans = min(ans,maxn(i,f[i]));
    57     }
    58     printf("%d",ans);
    59     return 0;
    60 } 
  • 相关阅读:
    传球接力
    业务办理
    P2077 红绿灯
    【UR #4】元旦激光炮
    P1939 【模板】矩阵加速(数列)
    #82. 【UR #7】水题生成器
    Visible Trees HDU
    创始人的领导力和合伙人选择
    面向对象笔试题练习一
    MicroPython+北斗+GPS+GPRS:TPYBoardv702短信功能使用说明
  • 原文地址:https://www.cnblogs.com/djfuuxjz/p/11836616.html
Copyright © 2020-2023  润新知