zoukankan      html  css  js  c++  java
  • hdu 2191 多重背包

      题目链接:hdu 2191

      题意很明显,数据规模也比较小,不过这题的数据还是很强的,多重背包我之前一直没有了解透切,所以也 wa 了不知多少次了,先来个朴素的比较暴力的版本:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define  sd(x)  scanf("%d",&(x))
     6 #define  sd2(x,y)  scanf("%d %d",&(x),&(y))
     7 #define  sd3(x,y,z)  scanf("%d %d %d",&(x),&(y),&(z))
     8 
     9 int dp[103][103];
    10 
    11 int main() {
    12     int t,n,m,p,h,c;
    13     sd(t);
    14     while(t--) {
    15         sd2(n,m);
    16         memset(dp, 0, sizeof(dp));
    17         for(int i = 1; i <= m; ++i) {
    18             sd3(p,h,c);
    19             for(int k = 0; k <= c; ++k)
    20                 for(int j = k * p; j <= n; ++j)
    21                     dp[i][j] = max(dp[i][j], dp[i - 1][j - k * p] + k * h);
    22         }
    23         printf("%d
    ",dp[m][n]);
    24     }
    25     return 0;
    26 }

      可以用滚动数组,不过只是得是 dp[2][103] 这样的至少两行数组,而不能是 dp[103] 的一行,因为在读入 p, h, c 后有两个循环的,因此 dp[i-1][j-k*p] 的值就会被多次用到,不能像简单的 01背包、完全背包那样一个循环之后就被会覆盖掉,就是因为这个问题 wa 了好几次,唉,都是模板记得太熟了。

      然后,我看了背包九讲后,发现多重背包还是能作优化的:

      按照他说的我写了下程序,也能AC,代码如下:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define  sd(x)  scanf("%d",&(x))
     6 #define  sd2(x,y)  scanf("%d %d",&(x),&(y))
     7 #define  sd3(x,y,z)  scanf("%d %d %d",&(x),&(y),&(z))
     8 
     9 int dp[103];
    10 
    11 int main() {
    12     int t,n,m,p,h,c;
    13     sd(t);
    14     while(t--) {
    15         sd2(n,m);
    16         memset(dp, 0, sizeof(dp));
    17         while(m--) {
    18             sd3(p,h,c);
    19             if(p * c >= n /*&& 0*/) {       // 完全背包这部分其实并不是必须的,一样可以 AC
    20                 for(int j = p; j <= n; ++j)
    21                     dp[j] = max(dp[j], dp[j - p] + h);
    22             }
    23             else {
    24                 int k = 1;
    25                 while(k <= c) {                 // 对转换后的每种物品用 01 背包来实现
    26                     for(int j = n; j >= p * k; --j)
    27                         dp[j] = max(dp[j], dp[j - p * k] + h * k);
    28                     c -= k;
    29                     k <<= 1;
    30                 }
    31                 if(c)                            // 最后作判断一下
    32                 for(int j = n; j >= p * c; --j)
    33                     dp[j] = max(dp[j], dp[j - p * c] + h * c);
    34             }
    35         }
    36         printf("%d
    ",dp[n]);
    37     }
    38     return 0;
    39 }
    优化的多重背包
  • 相关阅读:
    bzoj3033
    noip2016 Day1T3
    编译php的问题
    JavaScript <script>标签的位置、延迟脚本(defer属性)与 异步脚本(async属性)
    连接远程数据库时出现 SSH: expected key exchange group packet from server / 2003
    laravel中使用的PDF扩展包——laravel-dompdf和laravel-snappy
    laravel 生成 key
    windows下apache配置虚拟主机
    composer设置忽略版本匹配
    laravel 服务容器实例——深入理解IoC模式
  • 原文地址:https://www.cnblogs.com/Newdawn/p/4679679.html
Copyright © 2011-2022 走看看