首页 > 其他分享 >背包DP

背包DP

时间:2024-08-01 19:11:01浏览次数:12  
标签:背包 int 复杂度 cin DP 物品 dp

背包DP是线性DP中一种特殊的DP。

01背包

最基础的背包,有 \(n\) 件物品,背包容量为 \(V\),每件物品只有一件。可以使用空间优化,一般是原地滚动,此时注意容量需要从后往前更新,否则会一个状态更新多次。时间复杂度为 \(O(nV)\)。

核心代码

void solve() {
    int n, V;
    cin >> n >> V;
    for (int i = 1; i <= n; i++) {
        cin >> v[i] >> w[i];
    }
    for (int i = 1; i <= n; i++) {
        for (int j = V; j >= v[i]; j--) {            // 注意倒序更新
            dp[j] = max(dp[j], dp[j - v[i]] + w[i]); // 体积均为j,取价值最大的
        }
    }
    cout << dp[V] << "\n";
}

例题
装箱问题
01背包问题
开心的金明
采药

完全背包

有 \(n\) 件物品,背包容量为 \(V\),每件物品有无穷件。可以使用空间优化,一般是原地滚动,与01背包恰好相反,此时容量从前往后更新即可。复杂度为 \(O(nV)\)。

核心代码

void solve() {
    int n, V;
    cin >> n >> V;
    for (int i = 1; i <= n; i++) {
        cin >> v[i] >> w[i];
    }
    for (int i = 1; i <= n; i++) {
        for (int j = v[i]; j <= V; j++) {
            dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
        }
    }
    cout << dp[V] << "\n";
}

例题
完全背包问题

分组背包

有 \(n\) 组物品,背包容量为 \(V\),每组物品只能选一个。需要注意循环顺序,先对容量循环,再对每一组中的物品循环,因为每组中的物品相当于一组的一个状态,这些状态之间是互斥的。时间复杂度为 O(\(\sum n \times V\))。

核心代码

void solve() {
    int N, V, S;
    cin >> N >> V;
    vector<int> v[N + 1], w[N + 1], dp(V + 1);
    for (int i = 1; i <= N; i++) {
        cin >> S;
        v[i].resize(S);
        w[i].resize(S);
        for (int j = 0; j < S; j++) {
            cin >> v[i][j] >> w[i][j];
        }
    }

    for (int i = 1; i <= N; i++) {
        for (int j = V; j >= 0; j--) {
            for (int k = 0; k < v[i].size(); k++) {
                if (j >= v[i][k]) {
                    dp[j] = max(dp[j], dp[j - v[i][k]] + w[i][k]);
                }
            }
        }
    }

    cout << dp[V] << "\n";
}

例题
分组背包问题
小红升装备
小红组比赛

多重背包

有 \(n\) 组物品,背包容量为 \(V\),每组物品有有限个,其重量和价值相同。循环顺序为先对每一组中的物品循环,再对容量循环,若将多重背包中每组物品单独拿出来,可以看作01背包,而将物品进行组合可看作分组背包。时间复杂度为 O(\(\sum n \times V\))。可对每组中物品的组合进行优化,降低时间复杂度。

核心代码

void solve() {
    int N, V;
    cin >> N >> V;
    vector<int> v(N + 1), w(N + 1), s(N + 1), dp(V + 1);
    for (int i = 1; i <= N; i++) {
        cin >> v[i] >> w[i] >> s[i];
    }

    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= s[i]; j++) {
            for (int k = V; k >= v[i]; k--) {
                dp[k] = max(dp[k], dp[k - v[i]] + w[i]);
            }
        }
    }
    cout << dp[V] << "\n";
}

例题:
多重背包问题 I

标签:背包,int,复杂度,cin,DP,物品,dp
From: https://www.cnblogs.com/catting123/p/18337281

相关文章

  • 状压DP
    状压DP(BitmaskDP)将状态压缩为二进制表示,用于处理状态复杂的问题。主要分为一维和二维两种类型。一维状压DP最经典的是求最短哈密顿路径,对应\(n\)个结点的带权无向图,暴力枚举所有情况的时间复杂度为\(O(n)\),但是我们思考一下,到达某个顶点时,需要记录在这之前已经走过结点是......
  • Luogu P1613 跑路 题解 [ 蓝 ] [ 倍增 ] [ Floyd 最短路 ] [ 状压 dp ]
    跑路:绝佳倍增好题,思路是化\(2^k\)为\(1\),倍增起预处理作用。最近不知道是撞了什么运,前一脚看的是绿题,写完之后交一发,发现直接被lxl升蓝了,血赚。思路:Floyd首先观察到每次走\(2^k\)的代价为\(1\),我们可以预处理出每次走\(2^i\)能到哪些点。但为了让这题的代码更好实......
  • 为什么 DDoS 攻击偏爱使用 TCP 和 UDP 包?
    DistributedDenialofService(DDoS)攻击是指攻击者利用多个计算机系统或网络设备(通常是被恶意软件感染的计算机,被称为“僵尸网络”)来淹没目标服务器的资源,导致合法用户无法访问服务。TCP和UDP是两种最常见的用于DDoS攻击的网络协议。1.TCP和UDP的特性TCP(Tr......
  • 在AWS Lightsail建立WordPress Multisite & Route 53 subdomains & Hexo Blog & WordP
    1.0前言玩Startup比賽,因需高效快速地做POC原型產品,所以利用AWS云端服務來更快地開發。你會學到:LightSail建立WordpressmultisiteRoute53註冊WordpressSubdomains&GithubCuostomDomainLightSailCustomDomain&SSLHexo快速搭建GihubPages博客+ Route53 Custom......
  • Codeforces 11D A Simple Task 题解 [ 蓝 ] [ 状压 dp ]
    思路不难想,细节比较多。思路观察到\(n\le19\),首先想到状压dp。于是自然地定义\(dp[j][i]\)为:抵达点的状态为\(i\),且此时在点\(j\)时,简单路径的条数。注意这里是简单路径的条数,而不是环的个数,因为环的个数要在dp过程中统计。这里的dp作用就在于求简单路径条数。......
  • Transport Layer Security for UDP&TCP(TLS/DTLS1.2)
    参考文章:https://blog.csdn.net/alwaysrun/article/details/89076492 https://www.jianshu.com/p/fd0a624d0912 https://cloud.tencent.com/developer/article/1928677文档:https://www.rfc-editor.org/rfc/rfc6347  https://www.rfc-editor.org/rfc/rfc52461.SSL/TL......
  • 代码随想录训练第三十天|01背包理论基础、01背包、LeetCode416.分割等和子集
    文章目录01背包理论基础01背包二维dp数组01背包一维dp数组(滚动数组)416.分割等和子集思路01背包理论基础背包问题的理论基础重中之重是01背包,一定要理解透!leetcode上没有纯01背包的问题,都是01背包应用方面的题目,也就是需要转化为01背包问题。所以我先通过纯01背......
  • 代码随想录训练第三十二天|完全背包理论基础、LeetCode518.零钱兑换II、LeetCode377.
    文章目录完全背包理论基础完全背包总结518.零钱兑换II思路一维数组二维数组377.组合总和Ⅳ思路卡码网70.爬楼梯(进阶版)思路完全背包理论基础完全背包有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品都有无......
  • 代码随想录训练第三十三天|LeetCode322. 零钱兑换、LeetCode279.完全平方数、LeetCode
    文章目录322.零钱兑换思路279.完全平方数思路139.单词拆分思路多重背包背包总结遍历顺序01背包完全背包总结322.零钱兑换给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。计算并返回可以凑成总金额所需的最少的硬币个数。如果......
  • 一种优化 01 可行背包的方法
    source:abc221g有\(n\)个物品,体积分别为\(a_{1,2,\dots,n}\),要求从中选出若干个物品使得体积和为\(V\)。令\(A=\maxa_i\),\(V\lenA\)。一般的01背包做法是\(O(n^2A)\)的,但存在一种相对简单的做法可以做到复杂度\(O(nA)\)。下面描述这个做法。首先任意排列这个物......