• 完全背包


    问题描述:

    基本思路:

    这个问题和 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;
    }
  • 相关阅读:
    sitemap.xml
    Java--调试--单步调试,断言,单元测试
    同时显示多个 Notification
    HttpURLConnection请求数据流的写入(write)和读取(read)
    Spring jdbc 对象Mapper的简单封装
    mongodb之java CRUD 简单操作
    第三章 AOP 基于@AspectJ的AOP
    从源码角度深入分析log4j配置文件使用
    log4j.properties文件配置--官方文档
    JS问题Uncaught ReferenceError:XXXX is not defined
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12250260.html
Copyright © 2020-2023  润新知