当前位置:首页 > 牛客题解 > 背包问题的终极进化:牛客DP41题解与性能突破

背包问题的终极进化:牛客DP41题解与性能突破

2周前 (05-22)牛客题解55

截图未命名.jpg 背包问题的终极进化:牛客DP41题解与性能突破 牛客 01背包 动态规划 01背包变体 算法 C++ 第1张

题目分析

牛客DP41是01背包的变种问题,要求选择若干物品放入容量为V的背包,使总价值最大。特殊约束条件为:每个物品有数量限制(多重背包问题)。

核心思路

  1. 问题转化:将多重背包通过二进制拆分转为01背包问题

  2. 状态定义:dp[j]表示容量为j时的最大价值

  3. 转移方程

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

算法优化

  • 二进制拆分:将k个相同物品拆分为1,2,4...2^(n-1),k-2^n+1的组合

  • 空间优化:使用一维数组逆序更新

C++实现(带注释)

#include<bits/stdc++.h>
using namespace std;
const int N = 2010;

int dp[N];
struct Good {
    int v, w;
};

int main() {
    vector<Good> goods;
    int n, V;
    cin >> n >> V;
    
    // 二进制拆分处理
    for(int i = 0; i < n; i++) {
        int v, w, s;
        cin >> v >> w >> s;
        for(int k = 1; k <= s; k *= 2) {
            goods.push_back({v*k, w*k});
            s -= k;
        }
        if(s > 0) goods.push_back({v*s, w*s});
    }

    // 01背包处理
    for(auto good : goods)
        for(int j = V; j >= good.v; j--)
            dp[j] = max(dp[j], dp[j - good.v] + good.w);

    cout << dp[V];
    return 0;
}



原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。