zoukankan      html  css  js  c++  java
  • 背包九讲之一(01背包)

      1 /*
      2 有n个物品和一个容量为V的背包,第i件物品的费用是c[i],价值是w[i]
      3 求解哪些物品装入背包使价值总和最大
      4 dp[i][j]  dp[i][j] 为前i件物品放进容量为j的背包的最大价值
      5 dp[i][j] = max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]);
      6 */
      7 #include <stdio.h>
      8 #include <string.h>
      9 int dp[111][1111];
     10 int dp2[1001];
     11 int c[111],w[111];
     12 bool flag[111];
     13 inline int max(const int &a, const int &b)
     14 {
     15     return a < b ? b : a;
     16 }
     17 int main()
     18 {
     19     int n,v,i,j;
     20     while(scanf("%d%d",&n,&v)!=EOF)
     21     {
     22         memset(dp,0,sizeof(dp));
     23         dp2[0] = 0;
     24         for(i=1; i<=n; ++i)
     25             dp2[i] = 1<<30;
     26         memset(flag,false,sizeof(flag));
     27         for(i=1; i<=n; ++i)
     28             scanf("%d",&w[i]);
     29         for(i=1; i<=n; ++i)
     30             scanf("%d",&c[i]);
     31         for(i=1; i<=n; ++i)//时间空间复杂度均为O(VN)
     32             for(j=0; j<=v; ++j)
     33             {
     34                 dp[i][j] = dp[i-1][j];
     35                 if(j>=c[i])
     36                     dp[i][j] = max(dp[i][j],dp[i-1][j-c[i]]+w[i]);
     37             }
     38         for(i=1; i<=n; ++i)
     39         for(j=v; j>=0; --j)
     40         {
     41             if(j>=c[i])
     42                 dp2[j] = max(dp2[j],dp2[j-c[i]]+w[i]);
     43         }
     44         printf("%d
    ",dp[n][v]);
     45         printf("%d
    ",dp2[v]);
     46         /*时间复杂度不能优化了,但是空间可以优化到O(V)
     47         for(i=1; i<=n; ++i)
     48         for(j=v; j>=0; --j)//将循环改为这样也是成立的
     49         那么每一个dp[i][j] 都是继承自上一层的dp[i-1][j] 或者dp[i-1][j-c[i]]
     50         那么j是大于等于j或者j-c[i]的。
     51         那么就可以这样
     52         for(i=1; i<=n; ++i)
     53         for(j=v; j>=c[i]; --j)//必须是从后忘前
     54         {
     55             dp2[j] = max(dp2[j],dp[j-c[i]+w[i]]);//这一层继承继承自上一层,这种数组叫做滚动数组
     56         }
     57         */
     58         //下面是判断哪几个背包被选
     59         int Max = dp[n][v];
     60         for(i=n; i>=1; --i)
     61         {
     62             if(dp[i-1][v]>= Max)
     63                 flag[i] = false;
     64             else
     65             {
     66                 flag[i] = true;
     67                 v -= c[i];
     68                 Max -= w[i];
     69             }
     70         }
     71         if(flag[1])
     72                 printf("1");
     73             else
     74                 printf("0");
     75         for(i=2; i<=n; ++i)
     76             if(flag[i])
     77                 printf(" 1");
     78             else
     79                 printf(" 0");
     80         printf("
    ");
     81     }
     82     return 0;
     83 }
     84 /*
     85 5 10
     86 6 3 5 4 6
     87 2 2 6 5 4
     88 Sample Output:
     89 15
     90 1 1 0 0 1
     91 */
     92 /*
     93 另外还有就是求背包的最优解过程中,有两种要求:
     94 (1)要求背包装满,且价值最大(所以可能导致无解的情况发生)
     95 (2)只要求价值最大
     96 这两种问法差别在于初始化
     97 (1)将dp[0][0]初始化为0,其他的初始化为-INF,这是由题目的性质导致的
     98     初始的时候什么都不装,但是背包有容量而没装满是不合法的,所以定义-INF为不合法的
     99     如果要求背包装满,那么dp[i][j]表示的含义就变为了前i个物品装满容量为j的背包的最大价值
    100     dp[i][j] = max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]);
    101     如果dp[i-1][j],dp[i-1][j-c[i]]+w[i] ,这两个状态是不合法的,那么dp[i][j]也是不合法的
    102 (2)都初始化为0
    103         
    104 */
  • 相关阅读:
    鹅厂女专家:用“爱折腾”实现跨界之美
    基于腾讯云的视频聊天研究
    iOS微信内存监控
    2017年数据库技术盘点
    如何做好游戏内实时语音体验
    腾讯云微计算实践:从Serverless说起,谈谈边缘计算的未来
    使用腾讯云“自定义监控”监控GPU使用率
    如何在Python中从零开始实现随机森林
    DataGridView 设置某个列为只能为数字
    Ieditor
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4278581.html
Copyright © 2011-2022 走看看