01背包问题:
有n个重量和价值分别为wi,vi的物品。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。
1<=n<=100 1<= wi,vi<=100 1<=W<=10000
记忆化搜索:
#include <stdio.h>
#include <string.h>
#define max(x,y) ((x)>(y)?(x):(y))
int n, W;
int w[101];
int v[101];
int dp[101][101];
int rec(int i, int j) {
if(dp[i][j] >= 0) return dp[i][j];
int res;
if(i == n) {
res = 0;
}
else if(j < w[i]) {
res = rec(i + 1, j);
}
else {
res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + v[i]);
}
return dp[i][j] = res;
}
int main() {
scanf("%d%d",&n,&W);
for(int i = 0; i < n; i++) {
scanf("%d%d",&w[i],&v[i]);
}
memset(dp, -1, sizeof(dp));
printf("%d\n",rec(0, W));
return 0;
}dp[][]解法
#include <stdio.h>
#include <string.h>
#define max(x,y) ((x)>(y)?(x):(y))
int n, W;
int w[101];
int v[101];
int dp[101][101];
void solve() {
for(int i = n-1; i >= 0; i--) {
for(int j = 0; j <= W; j++) {
if(j < w[i]) {
dp[i][j] = dp[i+1][j];
}
else {
dp[i][j] = max(dp[i+1][j], dp[i+1][j-w[i]] + v[i]);
}
}
}
}
int main() {
scanf("%d%d",&n,&W);
for(int i = 0; i < n; i++) {
scanf("%d%d",&w[i],&v[i]);
}
memset(dp, 0, sizeof(dp));
solve();
printf("%d\n",dp[0][W]);
return 0;
}dp[]解法#include <stdio.h>
#include <string.h>
#define max(x,y) ((x)>(y)?(x):(y))
int n, W;
int w[101];
int v[101];
int dp[101];
void solve() {
for(int i = 0; i < n; i++) {
for(int j = W; j >= w[i]; j--) {
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
}
}
}
int main() {
scanf("%d%d",&n,&W);
for(int i = 0; i < n; i++) {
scanf("%d%d",&w[i],&v[i]);
}
memset(dp, 0, sizeof(dp));
solve();
printf("%d\n",dp[W]);
return 0;
}
本文详细介绍了01背包问题的解决方法,包括记忆化搜索、二维动态规划和一维动态规划三种实现方式,并提供了完整的C语言代码示例。
1299

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



