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; }