zoukankan      html  css  js  c++  java
  • 完全背包

    问题描述:

    基本思路:

    这个问题和 01背包 问题非常的相似,只是 01背包 问题要求了每个物品我们最多可以选一次(选和不选两种选择),但是完全背包问题只要容量够我们可以无限制的选

    如果我们依然采取和 01背包 一样的状态的定义

    dp[i][j] 代表 前 i 个物品 容量为 j 的时候的最大价值

    那么状态转移方程也就出来了:

    dp[i][j]   =    max(dp[i][j],dp[i][j-k*v[i]]+w[i]);

    int dp[1010][1010];
    int v[1010],w[1010];
    
    int main() {
        int n,m;
        std::cin >> n >> m;
        for (int i = 1;i <= n;i++) {
            std::cin >> v[i] >> w[i];
        }
        for (int i = 1;i <= n;i++) {
            for (int j = 0;j <= m;j++) {for (int k = 0;k * v[i] <= j;k++) {
                    dp[i][j] = std::max(dp[i][j],dp[i-1][j-k*v[i]]+k*w[i]);
                }
            }
        }
        std::cout << dp[n][m] << std::endl;
        return 0;
    }

    但是稍微分析一下这个算法的时间复杂度 和 空间复杂度都是比较高的

    我们可以采取和之前 01背包 一样的优化方法去优化一下

    简单的优化:

    之前讲 01背包 采取滚动数组的方法去优化必须要从大往小更新,这是因为我们每次都是要之前的状态

    但是 完全背包 的话我们可以看作他是在 01背包的基础上取了之后再继续取,所以我们每次都是在更新之后的状态上进行更新,也就是我们要从小往大更新

    这样这个算法的复杂度就变成了 O(N * M)

    int dp[1010];
    
    int main() {
        int n,m;
        std::cin >> n >> m;
        for (int i = 1;i <= n;i++) {
            int v,w;
            std::cin >> v >> w;
            for (int j = v;j <= m;j++)
                dp[j] = std::max(dp[j],dp[j-v]+w);
        }
        std::cout << dp[m] << std::endl;
        return 0;
    }
  • 相关阅读:
    居中
    背景和内容
    Filter 解决web网页跳转乱码
    java内部类
    javascript 基础教程[温故而知新一]
    每隔一秒自动执行函数(JavaScript)
    详解 Android Activity 生命周期
    css 重新学习系列(3)
    css 重新学习系列(2)
    写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12250260.html
Copyright © 2011-2022 走看看