#include <stdio.h>
// 比较两个整数并返回较大值的函数
int max(int a, int b) {
return (a > b)? a : b;
}
// 使用动态规划解决0 - 1背包问题的函数
// 参数说明:
// w[]:存储各个物品重量的数组
// v[]:存储各个物品价值的数组
// n:物品的数量
// c:背包的容量
void f(int w[], int v[], int n, int c) {
// 创建二维数组d,用于保存中间结果
// d[i][j]表示前i个物品放入容量为j的背包中所能获得的最大价值
// 初始化二维数组d的所有元素为0,这里数组大小为[n + 1][c + 1],方便处理边界情况(包括i = 0或j = 0的情况)
int d[n + 1][c + 1] = {0};
// 外层循环,遍历每个物品,从第0个物品开始(包含边界情况)到第n个物品
for (int i = 0; i <= n; i++) {
// 内层循环,遍历背包的不同容量,从第0个单位容量开始(包含边界情况)到第c个单位容量
for (int j = 0; j <= c; j++) {
// 处理边界情况:当没有物品可放(i == 0)或者背包容量为0(j == 0)时
// 背包能获得的最大价值显然为0,所以将d[i][j]赋值为0
if (i == 0 || j == 0) {
d[i][j] = 0;
} else if (w[i] > j) {
// 如果当前物品的重量w[i]大于当前考虑的背包容量j,说明当前物品无法放入该容量的背包
// 则当前状态下能获得的最大价值就等于前i - 1个物品放入容量为j的背包中所能获得的最大价值
// 即保持d[i][j]的值与前一个物品状态下相同容量背包能获得的最大价值相同
d[i][j] = d[i - 1][j];
} else {
// 如果当前物品的重量w[i]小于等于当前考虑的背包容量j,说明当前物品有可能放入背包
// 此时需要在两种情况中取最大值来更新d[i][j]的值:
// 1. 不放入当前物品,即前i - 1个物品放入容量为j的背包中所能获得的最大价值,也就是d[i - 1][j]
// 2. 放入当前物品,此时背包容量变为j - w[i],那么能获得的价值就是当前物品的价值v[i]加上前i - 1个物品放入剩余容量背包中所能获得的最大价值d[i - 1][j - w[i]]
d[i][j] = max(d[i - 1][j], v[i] + d[i - 1][j - w[i]]);
}
}
}
// 输出前n个物品放入容量为c的背包中所能获得的最大价值
// 这里根据动态规划的计算结果,d[n][c]就是最终所求的最大价值
printf("%d", d[n][c]);
}
int main() {
// 定义数组v,用于存储各个物品的价值,数组大小为100
int v[100];
// 定义数组w,用于存储各个物品的重量,数组大小为100
int w[100];
// 定义变量n,用于存储物品的数量
int n;
// 定义变量c,用于存储背包的容量
int c;
// 从标准输入读取物品的数量n和背包的容量c
scanf("%d %d", &n, &c);
// 循环读取每个物品的价值和重量,并存入相应的数组v和w中
// 这里按照顺序依次读取每个物品的重量和价值,并分别存入w[]和v[]数组中
for (int i = 1; i <= n; i++) {
scanf("%d %d", &w[i], &v[i]);
}
// 调用函数f计算并输出在给定背包容量下能获得的最大价值
// 将存储物品重量的数组w、存储物品价值的数组v、物品数量n和背包容量c作为参数传递给函数f
f(w, v, n, c);
// 返回0,表示程序正常结束
return 0;
}
动态规划方法解决0-1背包【详细代码】
最新推荐文章于 2025-11-15 14:49:35 发布
7975

被折叠的 条评论
为什么被折叠?



