[C++]01背包问题
基本问题
有N件物品和一个容量为V 的背包。放入第
思路
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。 用子问题定义状态:即
核心代码
memset(F[0], 0, sizeof(F[0]));
for (int i = 1; i <= n; ++i) {
for (int v = 0; v <= V; ++v) {
if (v >= c[i]) F[i][v] = max(F[i-1][v], F[i-1][v-c[i]] + w[i]);
else F[i][v] = F[i-1][v];
}
}
for (int i = 0; i <= V; ++i) ans = max(ans, F[n][i]);
其时间复杂度和空间复杂度都是
memset(F, 0, sizeof(F));
for (int i = 1; i <= n; ++i) {
for (int v = V; v >= c[i]; --v) {
F[v] = max(F[v], F[v-c[i]] + w[i]);
}
}
for (int i = 0; i <= V; ++i) ans = max(ans, F[i]);
求方案数
看一道题:小A点菜
对于这类改变问法的问题,一般只需将状态转移方程中的
初始条件是
F[0][0] = 1;
for (int i = 1; i <= n; ++i) {
for (int v = 0; v <= V; ++v) {
if (v >= c[i]) F[i][v] = F[i-1][v] + F[i-1][v-c[i]];
else F[i][v] = F[i-1][v];
}
}
ans = F[n][V];
printf("%d\n", ans);
求装得尽量满
再看一题:装箱问题 [NOIp2001普及组第4题]
其实这里
memset(F, 0, sizeof(F));
for (int i = 1; i <= n; ++i) {
for (int v = V; v >= c[i]; --v) {
F[v] = max(F[v], F[v-c[i]] + c[i]);
}
}
for (int i = 0; i <= V; ++i) ans = max(ans, F[i]);
printf("%d\n", V - ans);
求所有体积可能
又来一题:积木城堡
求出每个高度的城堡数量。
for (int i = 0; i < n; ++i) {
int np = 0;
int now;
int sum = 0;
while (1) {
scanf("%d", &now);
if (now == -1) break;
a[++np] = now;
sum += now;
}
if (max_sum < sum) max_sum = sum;
memset(F, 0, sizeof(F));
F[0] = 1;
for (int j = 1; j <= np; ++j) {
for (int v = sum; v >= a[j]; --v) {
if (F[v-a[j]] && !F[v]) {
++h[v];
F[v] = 1;
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)