zoukankan      html  css  js  c++  java
  • 杭电1712 分组背包

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

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <set>
     8 #include <map>
     9 #include <vector>
    10 using namespace std;
    11 
    12 int max(int a, int b)
    13 {
    14     return a > b ? a : b;
    15 }
    16 int main()
    17 {
    18     int n, m, i, j, k, a[110][110], dp[110];
    19     while(~scanf("%d %d", &n, &m))
    20     {
    21         if(n == 0 && m == 0)
    22             break;
    23         for(i = 1; i <= n; i++)
    24             for(j = 1; j <= m; j++)
    25                 scanf("%d", &a[i][j]);
    26         memset(dp, 0, sizeof(dp));
    27         for(i = 1; i <= n; i++)
    28         {
    29             for(j = m; j > 0; j--)//一定要从大到小
    30             {
    31                 for(k = 0; k < j; k++)
    32                     dp[j] = max(dp[j], dp[k] + a[i][j - k]);
    33             }
    34         }
    35         printf("%d
    ", dp[m]);
    36     }
    37     return 0;
    38 }

    问题

    有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

    算法

    这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设f[k][v]表示前k组物品花费费用v能取得的最大权值,则有:

    f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i属于组k}

    使用一维数组的伪代码如下:

    for 所有的组k
        for v=V..0
            for 所有的i属于组k
                f[v]=max{f[v],f[v-c[i]]+w[i]}
    

    注意这里的三层循环的顺序,甚至在本文的第一个beta版中我自己都写错了。“for v=V..0”这一层循环必须在“for 所有的i属于组k”之外。这样才能保证每一组内的物品最多只有一个会被添加到背包中。

    另外,显然可以对每组内的物品应用P02中“一个简单有效的优化”。

  • 相关阅读:
    footer在最低显示
    jQuery toast message 地址 使用
    linux 获取经过N层Nginx转发的访问来源真实IP
    Java Json格式的字符串转变对象
    多个机器获取微信access-token导致的有效性问题
    站点技术---301重定向
    C++技术问题总结-第8篇 STL内存池是怎么实现的
    IIS中遇到无法预览的问题(HTTP 错误 401.3
    梯度下降深入浅出
    COM-IE-(2)
  • 原文地址:https://www.cnblogs.com/luomi/p/5467416.html
Copyright © 2011-2022 走看看