动态规划5-多重背包
有一个背包容积是v,有n种物品,第i种物品的体积是vi,重量是wi,最多mi个,求如何放入物品可以使背包装入的重量最重。
这个与完全背包非常相似了,唯一的区别是个数,我们只需要在遍历个数循环的时候再加一个条件判断即可。
vector<int> nums = { 2, 3, 2, 1, 4 }; void zobag(vector<int>& weights, vector<int>& wealths, int vbag, int index, map<int, int>& selmap) { if (index < 0) { return; } else { map<int, int> selmap2 = selmap; for (int i = 0; i <= vbag / weights[index]; i++) { map<int, int> selmap1 = selmap; if (vbag >= i * weights[index] && i <= nums[i]) { selmap1[index] = i; } zobag(weights, wealths, vbag - i * weights[index], index - 1, selmap1); int tmp1 = 0; int tmp2 = 0; //int tmpw1 = 0; for (auto& iter : selmap1) { int a = iter.second; while (a > 0) { tmp1 += wealths[iter.first]; //tmpw1 += weights[iter.first]; a--; } } for (auto& iter : selmap2) { int a = iter.second; while (a > 0) { tmp2 += wealths[iter.first]; a--; } } /*if (tmpw1 != 10) { tmp1 = 0; selmap1.clear(); }*/ if (tmp1 > tmp2) { selmap2 = selmap1; } } selmap = selmap2; } } int main() { int vbag = 10; vector<int> weights = { 5, 3, 4, 3, 5 }; vector<int> wealths = { 500, 200, 300, 350, 400 }; map<int, int> selmap; zobag(weights, wealths, vbag, weights.size() - 1, selmap); for (auto& iter : selmap) { int a = iter.second; while (a > 0) { cout << iter.first << endl; a--; } } char inchar; cin >> inchar; }
int main() { int vbag = 10; vector<int> weights = { 5, 3, 4, 3, 5 }; vector<int> wealths = { 500, 200, 300, 350, 400 }; vector<int> nums = { 2, 3, 2, 1, 4 }; int* dp = new int[(10 + 1) * 5]();//多一个,方便用索引直接表示内容 int maxdp = 0; int maxi = 0; int maxj = 0; for (int vbgi = 0; vbgi < 10 + 1; vbgi++) { for (int i = 0; i < 5; i++) { if (vbgi == 0) { *(dp + vbgi * 5 + i) = 0; } else { int optw = 0; int wi = 0; while (vbgi >= weights[i] * wi && wi <= nums[i]) { int tmpoptw = wealths[i] * wi; if (i - 1 >= 0) { tmpoptw = tmpoptw + *(dp + (vbgi - weights[i] * wi) * 5 + i - 1); } if (tmpoptw > optw) { optw = tmpoptw; } wi++; } if (optw > maxdp) { maxdp = optw; maxi = i; maxj = vbgi; } //这里注意赋值 *(dp + vbgi * 5 + i) = optw; } } } while (*(dp + maxj * 5 + maxi) > 0 && maxi >= 0 && maxj >= 0) { //这里需要遍历找到第一个满足的条件,因为后面的会取前面的最大值 for (int i = 0; i < maxi; i++) { if (*(dp + maxj * 5 + i) == *(dp + maxj * 5 + maxi)) { maxi = i; break; } } //这里注意从1开始遍历,因为表示装了几个 for (int i = 1; i <= *(dp + maxj * 5 + maxi) / wealths[maxi]; i++) { cout << wealths[maxi] << endl; } maxj = maxj - *(dp + maxj * 5 + maxi) / wealths[maxi] * weights[maxi]; maxi--; } char inchar; std::cin >> inchar; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏