zoukankan      html  css  js  c++  java
  • 背包九讲之二(完全背包)

     1 /*
     2 有n种物品和一个容量为v的背包,每件物品可以无限使用,
     3 第i件物品的费用为c[i],价值为w[i],求解哪些物品装入背包
     4 费用不超过背包容量且价值总和最大
     5 基本思路是dp[i][j] = max{dp[i-1][j-k*c[i]] k*c[i]<=j}
     6 和01背包一样有V*N个状态,但是每个状态的求解不再是O(1)了,
     7 求解状态dp[i][j]是O(j/c[i]),总的时间复杂度超过O(V*N)
     8 
     9 可以转化为01背包问题从而求解
    10 (1)第i件物品可以转化为v/c[i]件物品,从而转化为01背包问题
    11 (2)一种更加好的方法是将第二种物品转化为费用c[i]*2^k,价值w[i]*2^k
    12     的若干件物品,其中k满足c[i]*2^k<=v.这是二进制的思想。因为不管最优策选择
    13     几件第i中物品,都可以用若干个2^k件物品来表示,这样就把每种物品拆分为
    14     log(v/c[i])种物品
    15 
    16 但是有更优的O(VN)算法
    17     for(i=1; i<=n; ++i)
    18     for(j=v[i]; j<=v; ++j)
    19         dp[j] = max(dp[j],dp[j-c[i]+w[i]);
    20 
    21 其实可以这么想  dp[i][j] = max(dp[i-1][j],dp[i][j-v[i]]+w[i]);
    22 dp[i][j]可以转化为上一层的dp[i-1][j],也可以转化为这一层左边的状态
    23 所以要求比j小的状态要算出来,所以要求j从0-->v
    24 就是
    25 for(i=1; i<=n; ++i)
    26     for(j=0; j<=v; ++j)
    27     {
    28         dp[i][j] = dp[i-1][j];
    29         if(j>=v[i])
    30             dp[i][j] = max(dp[i][j],dp[i][j-c[i]]+w[i]);
    31     }
    32 转化为一维的状态就是
    33 for(i=1; i<=n; ++i)
    34 for(j=v[i]; j<=v; ++j)
    35     dp[j] = max(dp[j],dp[j-c[i]]+w[i]);
    36 */
    37 #include <stdio.h>
    38 #include <string.h>
    39 int dp[111][1111];
    40 int dp2[1111];
    41 int c[111],w[111];
    42 inline int max(const int &a, const int &b)
    43 {
    44     return a < b ? b : a;
    45 }
    46 int main()
    47 {
    48     int n,v,i,j,k;
    49     while(scanf("%d%d",&n,&v)!=EOF)
    50     {
    51         for(i=1; i<=n; ++i)
    52             scanf("%d",&w[i]);
    53         for(i=1; i<=n; ++i)
    54             scanf("%d",&c[i]);
    55         memset(dp,0,sizeof(dp));
    56         memset(dp2,0,sizeof(dp2));
    57         for(i=1; i<=n; ++i)
    58         {
    59             for(j=0; j<=v; ++j)
    60             {
    61                 dp[i][j] = dp[i-1][j];
    62                 if(j>=c[i])
    63                 {
    64                     dp[i][j] = max(dp[i][j],dp[i][j-c[i]]+w[i]);
    65                     dp2[j] = max(dp2[j],dp2[j-c[i]]+w[i]);
    66                 }
    67             }                
    68         }
    69         
    70         printf("%d
    ",dp[n][v]);
    71         printf("%d
    ",dp2[v]);
    72     }
    73     return 0;
    74 }
    75 
    76 /*
    77 sample input:
    78 5 10
    79 1 2 5 4 6
    80 2 2 6 5 4
    81 
    82 sample output:
    83 
    84 */
  • 相关阅读:
    页面上有10个多选框,实现三个按钮(重置、反选、全选)功能
    鼠标点哪 哪出15*15的圆型div
    es写简单的留言板
    面试准备(3)事件循环
    面试准备(2)async+await的使用与原理
    面试准备(1)重排与重绘和验证码
    vue项目修改el-input样式
    echarts画雷达图详解
    决心
    国庆中秋
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4278759.html
Copyright © 2011-2022 走看看