【bzoj1222】[HNOI2001]产品加工 背包dp

题目描述

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

输入

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

输出

最少完成时间

样例输入

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

样例输出

9



题解

背包dp

由于可以把所有需要共同加工的产品在一开始就一起加工完,然后在各自加工各自的,所以产品之间是互不影响的。

于是就可以设$f[i][j]$表示加工前$i$个物品,A花费时间为$j$时,B花费的最小时间。那么直接跑背包dp即可。由于内存限制,需要使用滚动数组。

时间复杂度$O(3n*5n)=O(能过)$。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[2][30010];
inline void gmin(int &a , const int &b)
{
    if(a > b) a = b;
}
int main()
{
    int n , m , i , d , a , b , c , j , ans = 1 << 30;
    scanf("%d" , &n) , m = 5 * n;
    memset(f , 0x3f , sizeof(f)) , f[0][0] = 0;
    for(i = d = 1 ; i <= n ; i ++ , d ^= 1)
    {
        scanf("%d%d%d" , &a , &b , &c);
        memset(f[d] , 0x3f , sizeof(f[d]));
        if(a) for(j = a ; j <= m ; j ++ ) gmin(f[d][j] , f[d ^ 1][j - a]);
        if(b) for(j = 0 ; j <= m ; j ++ ) gmin(f[d][j] , f[d ^ 1][j] + b);
        if(c) for(j = c ; j <= m ; j ++ ) gmin(f[d][j] , f[d ^ 1][j - c] + c);
    }
    for(i = 1 ; i <= m ; i ++ ) gmin(ans , max(i , f[n & 1][i]));
    printf("%d\n" , ans);
    return 0;
}
时间: 2024-11-16 13:38:03

【bzoj1222】[HNOI2001]产品加工 背包dp的相关文章

bzoj1222: [HNOI2001]产品加工

注意时间都是 <= 5的.. 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<iostream> 6 7 using namespace std; 8 9 template<typename Q> Q read(Q& x) { 10 static char c, f; 11 for(f

bzoj 1222: [HNOI2001]产品加工 dp

1222: [HNOI2001]产品加工 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 381  Solved: 218[Submit][Status][Discuss] Description 某 加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所 需的时间会不同,若同时由两台机器共同进行加工,所完成任务又会不同.某一天,加工厂接到n个产品加工的任务,

[BZOJ 1025] 游戏 置换群 背包DP

题意 对于一个 $n$ 阶置换群 $A$ , 它的循环节大小分别为 $a_1, a_2, ..., a_m$ , 则有 $\sum_{i = 1} ^ m a_i = n$ . 定义 $f(A)$ 为它的所有循环节的最小公倍数, 即 $f(A) = [a_1, a_2, ..., a_m]$ . 求在所有 $n$ 阶置换群中, $f(A)$ 有多少种取值. $n \le 1000$ . 分析 判断 $K$ 可不可取. $K = \prod_{i = 1} ^ r {s_r} ^ {t_r}$ 可

hdu 5234 Happy birthday 背包 dp

Happy birthday Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5234 Description 今天是Gorwin的生日.所以她的妈妈要实现她的一个愿望.Gorwin说她想吃很多蛋糕.所以他妈妈带她来到了蛋糕园. 这个园子被分成了n*m个方格子.在每一个格子里面,有一个蛋糕.第i行,第j列的格子中有一个重量为wij千克的蛋糕,Gorwin从左上角(1,1

hdu 1171 Big Event in HDU(背包DP)

题意: 杭电搬迁,有N种设备,每种设备有个价值V,数量M,要求将这些设备平分,使得平分后两边的总价值尽可能地相等. 输出两边各自的总价值. 思路: 背包DP后,P=所有的总价值/2,然后从P开始往两边找到第一个满足的价值. 可以降维,但是要注意for循环的顺序. 看代码. 代码: int v[55], m[55]; bool dp[250005]; int main(){ int n; while(scanf("%d",&n)!=EOF && n>=0){

POJ 1384 Piggy-Bank 背包DP

所谓的完全背包,就是说物品没有限制数量的. 怎么起个这么intimidating(吓人)的名字? 其实和一般01背包没多少区别,不过数量可以无穷大,那么就可以利用一个物品累加到总容量结尾就可以了. 本题要求装满的,故此增加个限制就可以了. #include <stdio.h> #include <stdlib.h> #include <string.h> inline int min(int a, int b) { return a < b? a : b; } c

BZOJ 1042 硬币购物(完全背包+DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1042 题意:给出四种面值的硬币c1,c2,c3,c4.n个询问.每次询问用d1.d2.d3.d4个相应的硬币能够拼出多少种总和为s? 思路:(1)首先,用完全背包求出f[i]表示四种硬币的数量无限制拼出i的方案数. (2)接着我们来理解 x=f[s]-f[s-(d1+1)*c1]的含义:x表示c1硬币的数量不超过d1个而其他三种硬币的数量不限制拼成s的方案数.我们举着例子来说明, 假设

HDU 5616 Jam&#39;s balance 背包DP

Jam's balance Problem Description Jim has a balance and N weights. (1≤N≤20)The balance can only tell whether things on different side are the same weight.Weights can be put on left side or right side arbitrarily.Please tell whether the balance can me

hdu1561:树形背包dp

给定n个地点,每个地点藏有cost[i]的宝物,取得某些宝物有时需要先取其他宝物,现在让我们选m个地点问最多可以选多少宝物? 还是挺裸的树形背包dp吧,不难,关键还是中间dp的部分.可以做模板了->_-> 注意点:多组数据的话如果第一组对了然后其他都错了,那么很有可能是初始化的时候漏了.这次找可很久才知道差了e[0].clear().平时的习惯都是从1开始. --------------------------------------------------------------------