zoukankan      html  css  js  c++  java
  • hdu 5445 Food Problem (多重背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5445

    题解:一看就像多重背包就是怎么看都不好做。但是这里有点明显的就是有两个背包,一个是糖果一个是箱子,于是不妨就试试两个多重背包,先考虑用这些糖果能否满足条件设dp[i]表示构成能量为i的糖果最小需要多少体积,然后将所需要的体积保存下来那么只要找到一些箱子总共能容纳的体积大于等于这个值就行这时的dp[i]又表示容积总共是i的箱子最少需要多少钱。其实这样也是不够严谨的因为这样也不能保证糖果刚好能放好但是理论上是可行的。还有要注意的就是多重背包要注意二进制的优化。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 2e5 + 10;
    const int Max = 50000 + 10;
    int dp[M];
    int t[M] , u[M] , v[M];
    int x[M] , y[M] , z[M];
    int main() {
        int test , n , m , q;
        scanf("%d" , &test);
        while(test--) {
            int ans = inf;
            scanf("%d%d%d" , &n , &m , &q);
            for(int i = 0 ; i < n ; i++) {
                scanf("%d%d%d" , &t[i] , &u[i] , &v[i]);
            }
            for(int i = 0 ; i < m ; i++) {
                scanf("%d%d%d" , &x[i] , &y[i] , &z[i]);
            }
            memset(dp , inf , sizeof(dp));
            dp[0] = 0;
            for(int i = 0 ; i < n ; i++) {
                int mm = v[i];
                for(int j = 1 ; mm > 0 ; j <<= 1) {
                    int gg = min(j , mm);
                    for(int l = Max ; l >= gg * t[i] ; l--) {
                        dp[l] = min(dp[l] , dp[l - gg * t[i]] + gg * u[i]);
                    }
                    mm -= j;
                }
            }
            for(int i = q ; i <= Max ; i++) {
                if(dp[i] != inf) {
                    ans = min(ans , dp[i]);
                }
            }
            memset(dp , 0 , sizeof(dp));
            for(int i = 0 ; i < m ; i++) {
                int mm = z[i];
                for(int j = 1 ; mm > 0 ; j <<= 1) {
                    int gg = min(j , mm);
                    for(int l = Max ; l >= gg * y[i] ; l--) {
                        dp[l] = max(dp[l] , dp[l - gg * y[i]] + gg * x[i]);
                    }
                    mm -= j;
                }
            }
            int flag = 0;
            for(int i = 1 ; i <= Max - 10 ; i++) {
                if(dp[i] >= ans && ans != inf) {
                    flag = i;
                    break;
                }
            }
            if(flag) printf("%d
    " , flag);
            else printf("TAT
    ");
        }
        return 0;
    }
  • 相关阅读:
    设计手稿: 搜索引擎
    软件版本介绍
    VS2012中使用编译的Qt-5.1.1静态库开发程序
    POJ2236(并查集)
    Java关键字this的用法总结
    paip.提升用户体验-----c++ gcc 命令在notepad++扩展中的配置..
    MySQL基本查询语句练习
    [置顶] 提升代码内外部质量的22条经验
    mysql 数据库复制表 create table city1 like city;
    两个脚本
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7652597.html
Copyright © 2011-2022 走看看