zoukankan      html  css  js  c++  java
  • 动态规划的背包问题——01背包

    挺简单的,与完全背包差不多,只不过是所有的物品可以随便选改为了每个物品只能选一次

    状态设计(二维):设i为当前的物品,j为当前背包容量

    转移方程为f(i,j)=max{f(i-1,j),f(i-1,j-w[i])+v[i]} 其中w[i]为当前物品的重量,v[i]为当前物品的价值

    常规做法如下

    for(int i=1;i<=n;i++)//物品数
    {
        for(int j=0;j<=m;j++)//枚举容量 
        {
            if(j<w[i])//装不下肯定就不选
            {
                f[i][j]=f[i-1][j];
            }
            else//否则两种情况进行转移
            {
                f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
            }
        } 
    } 

    但这样空间复杂度为O(m*n),显然在m,n很大的情况下不得行

    所以我们可以采取优化

    我们看当前的最优解只与它的前一个有关,所以我们每次只更新这两个值即可

    法1 滚动数组优化

    int p=1,q=0;//只在这两行之间转移
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=m;j++)
        {
             if(j<w[i])
             {
                 f[p][j]=f[q][j];
            }
            else
            {
                f[p][j]=max(f[q][j],f[q][j-w[i]]+v[i]);
            }
        }
        swap(p,q); //滚起来
    } 

    法2 一维状态转移

    通过观察还可以优化至一维f[n]表示当前容量下的最大值

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

    可是你就会发现枚举容量的时候要倒序,这是为什么呢?

  • 相关阅读:
    埋点和用户画像
    HDR 2 数据集预处理
    HDR 1(介绍)
    关于AR
    Android驱动
    修改用户登陆次数
    使用plsql developer报错
    oracle客户端卸载
    项目:搜索查找
    使用BeautifulSoup模块解析HTML(文件example.html)
  • 原文地址:https://www.cnblogs.com/LJB666/p/10806103.html
Copyright © 2011-2022 走看看