• 背包问题(01背包)


    --------开始--------

             每次用到背包问题就忘,今天特意把背包问题写下来,本篇只写01背包问题,至于其它的背包问题以后会陆续出现,大多数背包问题都是以01背包为原型来演变过来的,所以先介绍经典的01背包问题。

             01背包问题是动态规划的典型例题,0  1顾名思义就是一个物品有两种情况,拿或者不拿,每种物品有且仅有一件,用子问题定义状态:即f[i][j]表示前i件物品恰放入一个容量为j的背包可以获得的最大价值。则其状态转移方程便是:

                                                                                                                     

    f[i][j]=max( f[i-1][j],f[i-1][j-v[i]]+w[i] )

          至于这个方程怎么推导出来的,我后面会介绍,总之,这个状态转移方程特别重要,其它背包问题的状态转移方程也都是又它衍生出来的,可以说它的作用非常重要。

          我们先来看下01背包的题目 :

    问题

    有 N 件物品和一个容量是 的背包。每件物品只能使用一次。

    第 件物品的体积是 v,价值是 wi 

    求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
    输出最大价值。

    输入格式

    第一行两个整数,NV,用空格隔开,分别表示物品数量和背包容积。

    接下来有 N 行,每行两个整数 vi wi ,用空格隔开,分别表示第 i 件物品的体积和价值。

    输出格式

    输出一个整数,表示最大价值。

    数据范围

    0<N,V10000<N,V≤1000
    0<vi,wi1000

    输入样例

    4 5
    1 2
    2 4
    3 4
    4 5

    输出样例:

    8

     问题特点很明确:每件物品只有一件我们可以选择拿或者不拿,我们定义v[ i ]为物品的体积,w[i]为物品的价值。

    我们再来看状态转移方程  f[ i ][ j ] = max ( f[ i-1 ][ j ] , f[ i-1 ][ j-v[ i ] ] + w[ i ] )

    f[i][j]就是前i件物品,在体积为j的情况下最大价值是多少。

    我们要计算在有限空间中怎么才能价值最大,可以通过转化求在n件物品和n-1件物品(放第n件物品或者不放)中求最大价值,所以我们需要求n-1件物品时的最大价值,进而类似递归需要求n-1件物品和n-2件物品中的最大值,一直到最后一件,从第一件推回第n件就是我们的结果。

    1. 选第i件物品 f[i][j] = f[i - 1][j - v[i]] ;

    2. 不选第i件物品 f[i][j] = f[i - 1][j] ;

    然后我们的答案就是res = max{ f[n][0V] } ;

     

         

    for(int i = 1;i <= n;i++)
          for(int j = 0;j <= m;j++)
          {
            f[i][j] = f[i-1][j];
              if(j >= v[i])
                  f[i][j] = max(f[i-1][j-v[i]]+w[i],f[i][j]); }
          int res=0;
          for(int i =0;i <= m;i++)
            res = max(res,f[n][i]);

    以上描述的方法的时间和空间复杂度均为O(VN),但是时间复杂度应该已经不能再优化了,而空间复杂度却可以优化到O(V),即可以把二维数组变成一维数组,至于如何优化会在下次再继续讲解。

    PS : 题目来源: https://www.acwing.com/problem/content/2/
    参考文章: https://blog.csdn.net/u013445530/article/details/40210587

    --------结束--------

  • 相关阅读:
    HTML 5 标准属性
    启程
    【Java】自定义登陆拦截器
    【Java】将List中的实体按照某个字段进行分组的算法
    SpringBoot + MultipartFile 实现文件上传以及文件转移的功能以及配置全局捕获上传文件过大异常
    MySQL查询两门及两门以上不及格的学生,显示姓名
    java中可以用==来比较两个字符串是否相等吗
    自己动手Jquery插件
    10个可以直接拿来用的JQuery代码片段
    linux 安装python
  • 原文地址:https://www.cnblogs.com/chuyds/p/10531006.html
Copyright © 2020-2023  润新知