zoukankan      html  css  js  c++  java
  • 背包九讲之七(有依赖的背包问题)

     1 /*
     2 即物品间存在依赖,比如i依赖于j,表示若选物品i,则必须选物品j
     3 http://acm.hdu.edu.cn/showproblem.php?pid=3449
     4 有很多个箱子,想买箱子中的物品必须先买下箱子,典型的依赖背包
     5 将不依赖其他物品的物品称为主件,依赖其他物品的物品称为附件
     6 我们有n个箱子,箱子里面的物品个数为cnt[i]
     7 那么箱子称为主件,箱子里面的物品称为附件
     8 那么考虑一个主件和它附件的集合,那么有2^n+1种策略,每种策略都是互斥的。所以它是分组背包问题。
     9 但是不能像一般的分组背包那样处理,因为组内有2^n+1种。
    10 但是考虑到费用相同时,只选择价值最大的。所以可以对组内的附件进行01背包,得到费用依次为v-c[i]...0的最大价值
    11 dp2[v-c[i]...0]
    12 
    13 */
    14 #include <stdio.h>
    15 #include <string.h>
    16 int dp[100000+10],dp2[100000+10];
    17 int box[55],cnt[55],price[55][11],value[55][11];
    18 inline int max(const int &a, const int &b)
    19 {
    20     return a < b ? b : a;
    21 }
    22 int main()
    23 {
    24     int n,v,i,j,k;
    25     while(scanf("%d%d",&n,&v)!=EOF)
    26     {
    27         memset(dp,0,sizeof(dp));
    28         for(i=1; i<=n; ++i)
    29         {
    30             scanf("%d%d",&box[i],&cnt[i]);
    31             memcpy(dp2,dp,sizeof(dp));
    32             for(j=1; j<=cnt[i]; ++j)
    33             {
    34                 scanf("%d%d",&price[i][j],&value[i][j]);
    35                 for(k=v-box[i]; k>=price[i][j]; --k)//附件进行01背包,每个dp2[k]对于组内的一种策略
    36                     dp2[k] = max(dp2[k],dp2[k-price[i][j]]+value[i][j]);
    37             }
    38             for(k=box[i];k<=v; ++k)
    39                 dp[k] = max(dp[k],dp2[k-box[i]]);//当容量为k时,取第i组的物品时得到的最大值和不取比较哪个大
    40         }
    41         printf("%d
    ",dp[v]);
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    在ACCESS中LIKE的用法
    pip 在windows下的更新升级
    NAS、SAN、DAS 说明
    RAID 工作模式
    Linux mail 邮件发送
    Linux 邮件服务搭建
    HA 脑裂原理
    Tomcat 工作原理
    Nagios 工作原理
    Nginx 工作原理
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4280286.html
Copyright © 2011-2022 走看看