zoukankan      html  css  js  c++  java
  • DP大作战—组合背包

    题目描述

    组合背包:有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。

    DD大牛的伪代码
    for i = 1 to N
        if 第i件物品属于01背包
            ZeroOnePack(F,Ci,Wi)
        else if 第i件物品属于完全背包
            CompletePack(F,Ci,Wi)
        else if 第i件物品属于多重背包
            MultiplePack(F,Ci,Wi,Ni)

    输入

    第一个数为数据组数n 1<=n<=10

    接下来n组测试数据,每组测试数据由2部分组成。

    第一行为背包容量V,物品种类数N。1<=V<=30000,1<=N<=200

    接下来N行每行三个数为物品价值v,物品重量w,物品件数M。M=233表示物品无限。

    1<=v,w<=200, 1<=M<=25

    输出

    对于每组数据,输出一行,背包能容纳的最大物品价值

    输入样例

    1
    10 3
    2 2 233
    3 2 1
    4 3 3

    输出样例

    13
    题目来源:http://biancheng.love/contest/10/problem/F/index
    解题思路:
    组合背包:0-1背包、完全背包、多重背包。
    因此需要结合上述三种背包问题的解决方法来solve组合背包
    0-1背包代码:
    1 void Zeronepack(int w,int v)
    2 {
    3     for(int i=V; i>=w; i--)
    4         if(dp[i]<dp[i-w]+v)
    5             dp[i]=dp[i-w]+v;
    6 }

    完全背包代码:

    1 void Compack(int w,int v)
    2 {
    3     for(int i=w; i<=V; i++)
    4         if(dp[i]<dp[i-w]+v)
    5             dp[i]=dp[i-w]+v;
    6 }

    多重背包代码:

     1 void Multipack(int w,int v,int num)
     2 {
     3     int k;
     4     if(w*num>=V)
     5     {
     6         Compack(w,v);
     7         return;
     8     }
     9     for(k=1; k<num; k<<1)
    10     {
    11         Zeronepack(k*w,k*v);
    12         num-=k;
    13     }
    14     Zeronepack(num*w,num*v);
    15 }

    本题组合背包代码:

     1 #include <bits/stdc++.h>
     2 int dp[30005];
     3 int V,N;
     4 
     5 void Compack(int w,int v)
     6 {
     7     for(int i=w; i<=V; i++)
     8         if(dp[i]<dp[i-w]+v)
     9             dp[i]=dp[i-w]+v;
    10 }
    11 
    12 void Zeronepack(int w,int v)
    13 {
    14     for(int i=V; i>=w; i--)
    15         if(dp[i]<dp[i-w]+v)
    16             dp[i]=dp[i-w]+v;
    17 }
    18 
    19 void Multipack(int w,int v,int num)
    20 {
    21     int k;
    22     if(w*num>=V)
    23     {
    24         Compack(w,v);
    25         return;
    26     }
    27     for(k=1; k<num; k<<1)
    28     {
    29         Zeronepack(k*w,k*v);
    30         num-=k;
    31     }
    32     Zeronepack(num*w,num*v);
    33 }
    34 
    35 int main()
    36 {
    37     int kase,v,w,m;
    38     scanf("%d",&kase);
    39     while(kase--)
    40     {
    41         memset(dp,0,sizeof(dp));
    42         scanf("%d%d",&V,&N);
    43         for(int i=1;i<=N;i++)
    44         {
    45             scanf("%d%d%d",&v,&w,&m);
    46             if(m==1)
    47                 Zeronepack(w,v);
    48             else if(m==233)
    49                 Compack(w,v);
    50             else
    51                 Multipack(w,v,m);
    52         }
    53         printf("%d
    ",dp[V]);
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    厂商前缀
    文本阴影和边框阴影
    2D转换
    overflow属性
    margin属性
    CSS圆角边框
    浮动定位
    文档流定位
    position属性
    选择器二
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/4991934.html
Copyright © 2011-2022 走看看