第一行输入两个整数
和
,分别表示物品数量与背包容量。
此后
行,第
行输入两个整数
,分别表示第
件物品的体积与价值。
输出两行:
第一行输出方案
的答案;
第二行输出方案
的答案(若无解输出
)。
3 5 2 10 4 5 1 4
14 9
在该组样例中:
选择第
、第
件物品即可获得最大价值
(未装满);
选择第
、第
件物品可使背包体积
恰好装满且价值最大,为
。
3 8 12 6 11 8 6 8
8 0
装第三个物品时总价值最大但是不满,装满背包无解。
要求
的时间复杂度,
空间复杂度。
#include <limits.h> #include <stdio.h> #include <string.h> int max(int a, int b) { return (a > b ? a : b); } int main() { int n, m; scanf("%d %d", &n, &m); int v[n + 1], w[n + 1], dp[m + 1]; v[0] = 0, w[0] = 0; for (int i = 1; i <= n; i++) { scanf("%d %d", &v[i], &w[i]); } memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { for (int j = m; j >= v[i]; j--) { dp[j] = max(dp[j], dp[j - v[i]] + w[i]); } } printf("%d\n", dp[m]); for (int i = 1; i <= m; i++) { dp[i] = INT_MIN; } for (int i = 1; i <= n; i++) { for (int j = m; j >= v[i]; j--) { dp[j] = max(dp[j], dp[j - v[i]] + w[i]); } } printf("%d",(dp[m]>0?dp[m]:0)); return 0; }
#include "stdio.h" #include "stdlib.h" // 抄榜一大佬的 int max(int a,int b) { return a>b?a:b; } int main() { int n,V; // 输入n, V scanf("%d%d",&n,&V); // 价值和重量 int *vi=(int*)malloc(sizeof(int)*n); int *wi=(int*)malloc(sizeof(int)*n); for(int i=0;i<n;i++) { scanf("%d %d",&vi[i],&wi[i]); } // dp内存 int *dp=(int*)malloc(sizeof(int)*(V+1)); dp[0]=0 ; // 小细节,这里不设置为0. 无法计算出正确答案 for(int i=1;i<V+1;i++) dp[i]=0x80000000; // -2147483648 int max_dp=0; // 第一问答案 int j; // 从上往下,从右往左:因为物品都只能用一次 for(int i=1;i<=n;i++) { for(j=V;j>=vi[i-1];j--) { dp[j]=max(dp[j-vi[i-1]]+wi[i-1],dp[j]); if(dp[j]>max_dp) // 第一问答案就是恰好在某个容量时,可以达到的最大价值。一直记录最大值,就可以得到 max_dp=dp[j]; // 记录更新第一问答案 } } printf("%d\n",max_dp); max_dp=dp[V]; free(dp); if(max_dp<0) printf("0"); else printf("%d",max_dp); }