背包问题的终极进化:牛客DP41题解与性能突破
题目分析
牛客DP41是01背包的变种问题,要求选择若干物品放入容量为V的背包,使总价值最大。特殊约束条件为:每个物品有数量限制(多重背包问题)。
核心思路
问题转化:将多重背包通过二进制拆分转为01背包问题
状态定义:dp[j]表示容量为j时的最大价值
转移方程:
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; }
原创内容 转载请注明出处