2 条题解
-
0
错误题解 您的代码中存在多个严重的语法和逻辑错误,导致它无法编译,也无法正确解决0-1背包问题。我们来逐一分析。
- 语法错误 可变长度数组 (VLA): int w[n+1], int v[n+1], int dp[n][c] 这种写法不是标准的C++,虽然某些编译器支持,但不推荐。数组的大小必须是编译时确定的常量。 缺少分号: 在 dp[i][j]=max(...) 这一行的末尾,缺少了一个分号 ;,这会导致编译失败。 未定义的变量: 在最后的输出循环 for(int i=1;i<n;i++){ cout<<dp[i][j]; } 中,变量 j 没有被定义。
- 逻辑错误 DP数组大小与索引:
您的DP数组定义为 dp[n][c],索引从 0 到 n-1 和 0 到 c-1。 但在循环中,您访问了 dp[i-1]。当 i=0 时,这会访问 dp[-1],导致数组越界,程序崩溃。 正确的做法是,DP表的大小应为 dp[n+1][c+1],循环从 i=1 到 n,j=1 到 c。 状态转移方程完全错误:
情况一:当前容量 j 装不下物品 i (j < w[i]) 您的代码:dp[i][j]=dp[i][j-1]; 这是错误的。 正确逻辑:如果装不下物品 i,那么最大价值应该等于只考虑前 i-1 个物品在同样容量 j 下的最大价值。即 dp[i][j] = dp[i-1][j];。 情况二:当前容量 j 装得下物品 i 您的代码:dp[i][j]=max(dp[i-1][j], dp[i-1][j-1]+v[j]) 这是错误的。 正确逻辑:我们需要在两种选择中取最大值: 不装物品 i:最大价值为 dp[i-1][j]。 装入物品 i:价值为“物品 i 的价值 v[i]”加上“用剩余容量 j - w[i] 去装前 i-1 个物品得到的最大价值 dp[i-1][j - w[i]]”。 所以,正确的转移方程是:dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]); 输出选择的物品(路径回溯):
题目要求输出一个01序列表示哪些物品被选中。这需要在计算出最大价值后,从 dp[n][c] 开始回溯DP表来找出决策路径。您的代码完全没有实现这个功能。
#include <bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; int w[n+1]={0}; int v[n+1]={0}; for(int i=1;i<=n;i++){ cin>>w[i]; } for(int i=1;i<=n;i++){ cin>>v[i]; } int c; cin>>c; int dp[n+1][c+1]={0}; for(int i=1;i<=n;i++){ for(int j=1;j<=c;j++){ if(j<w[i]){ dp[i][j]=dp[i-1][j]; }else{ dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]) } } } for(int i=1;i<n;i++){ cout<<dp[i][j]; }] cout<<'\n'; cout<<dp[n][c]; } -
0
C :
#include <stdio.h> #define max 20 int n,c,w[max],v[max],m[max][max]={0}; void knapsack() { int i,j; for (i=1; i<=n; i++) for (j=1; j<=c; j++) { m[i][j]=m[i-1][j]; if ( j>=w[i-1] && m[i-1][j-w[i-1]]+v[i-1]> m[i][j] ) m[i][j]=m[i-1][j-w[i-1]]+v[i-1]; } } void disp( ) { int i,j; int x[max]={0}; i=n; while ( m[i][c]==m[i-1][c] ) i--; while (i>1) { j=i-1; while (m[i][c]-m[j][c]!=v[i-1] && j>0) j--; x[i]=1; i=j; } for(i=2;i<=n;i++) printf("%d",x[i]); } int main( ) { int i,j; scanf("%d",&n); for (i=0; i<n; i++) scanf("%d",&v[i]); for (i=0; i<n; i++) scanf("%d",&w[i]); scanf("%d",&c); knapsack(); disp(); printf("\n"); printf("%d\n",m[n][c]); return 0; }C++ :
#include<iostream> using namespace std; int V[200][200]; int max(int a,int b) { if(a>=b) return a; else return b; } int p(int n,int w[],int v[],int x[],int C) { int i,j; for(i=0;i<=n;i++) V[i][0]=0; for(j=0;j<=C;j++) V[0][j]=0; for(i=0;i<=n-1;i++) for(j=0;j<=C;j++) if(j<w[i]) V[i][j]=V[i-1][j]; else V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]); j=C; for(i=n-1;i>=0;i--) { if(V[i][j]>V[i-1][j]) { x[i]=1; j=j-w[i]; } else x[i]=0; } for(i=1;i<n;i++) { cout<<x[i]; } cout<<"\n"; return V[n-1][C]; } int main() { int s; int w[15]; int v[15]; int x[15]; int n,i; int C; n=5; cin>>n; for(i=0;i<n;i++) cin>>v[i]; for(i=0;i<n;i++) cin>>w[i]; cin>>C; s=p(n,w,v,x,C); cout<<s<<"\n"; }Java :
import java.util.Scanner; //本程序取自王晓东编著“算法分析与设计”第 92 页,例 //0-1背包问题动态规划解法 class Math { public Math() { } static int min(int i, int j) { if (i > j) { return j; } else { return i; } } static int max(int i, int j) { if (i > j) { return i; } else { return j; } } } public class Main { public static void knapsack(int[] v, int[] w, int c, int[][] m) { int n = v.length - 1; int jMax = Math.min(w[n] - 1, c); for (int j = 0; j <= jMax; j++) { m[n][j] = 0; } for (int j = w[n]; j <= c; j++) { m[n][j] = v[n]; } for (int i = n - 1; i > 1; i--) { jMax = Math.min(w[i] - 1, c); for (int j = 0; j <= jMax; j++) { m[i][j] = m[i + 1][j]; } for (int j = w[i]; j <= c; j++) { m[i][j] = Math.max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]); } } m[1][c] = m[2][c]; if (c >= w[1]) { m[1][c] = Math.max(m[1][c], m[2][c - w[1]] + v[1]); } } public static void traceback(int[][] m, int[] w, int c, int[] x) { int n = w.length - 1; for (int i = 0; i < n; i++) { if (m[i][c] == m[i + 1][c]) { x[i] = 0; } else { x[i] = 1; c -= w[i]; } } x[n] = (m[n][c] > 0) ? 1 : 0; } public static void main(String args[]) { // int c1 = 10; Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int v1[] = new int[n];//{0,6, 3, 5, 4, 6}; int w1[] = new int[n];//{0,2, 2, 6, 5, 4}; for(int i=0;i<n;i++) { v1[i]=sc.nextInt(); } for(int i=0;i<n;i++) { w1[i]=sc.nextInt(); } int c1 = sc.nextInt(); // System.out.print("v1[]={"); // for (int i = 0; i < v1.length; i++) { // System.out.print(v1[i]); // } // System.out.print("}"); // System.out.println(); // System.out.print("w1[]={"); // for (int i = 0; i < w1.length; i++) { // System.out.print(w1[i]); // } // System.out.print("}"); // System.out.println(); // System.out.println("c=" + c1); int n1 = v1.length - 1; int x1[] = new int[n1 + 1]; int[][] m1 = new int[n1 + 1][c1 + 1]; knapsack(v1, w1, c1, m1); traceback(m1, w1, c1, x1); for (int i = 1; i <= n1; i++) { // if (x1[i] == 1) { System.out.print(x1[i]); // } } System.out.println(); System.out.println(m1[1][c1]); } }
- 1
信息
- ID
- 4230
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者