01背包dp具体解释详见链接 ↓
【算法5.1】背包问题 - 01背包 (至多最大价值、至少最小价值)_背包问题求最小价值_Roye_ack的博客-CSDN博客
关于如何求出最优物品选择方案?
- 先在递归求dp公式时,若进行【选择】则在决策表ck中标记ck[i][j]=1
- 遍历求完dp公式后,逆向遍历决策表,从最后一个物品开始,如果ck[i][j]=1且ck[i-1][j-w[i]]=1,则标记st[i]=st[i-1]=1
- import java.util.*;
-
- public class hdjs {
-
- public static void main(String[] args)
- {
- Scanner sc=new Scanner(System.in);
- System.out.println("请输入物品数量和背包容量!");
- int n=sc.nextInt(),m=sc.nextInt();
-
- int[] st=new int[n+1]; //记录最终物品选择情况
- int[][] ck=new int[n+1][m+1]; //记录物品选or不选决策情况
-
- int[] w=new int[n+1],v=new int[n+1];
- System.out.println("请依次输入物品重量!");
- for(int i=1;i<=n;i++) w[i]=sc.nextInt();
-
- System.out.println("请依次输入物品价值!");
- for(int i=1;i<=n;i++) v[i]=sc.nextInt();
-
- int[][] f=new int[n+1][1010]; //f[i][j] 选择前i个物品,体积不超过j的最大价值
-
- f[0][0]=0;
- for(int i=1;i<=n;i++)
- {
- for(int j=0;j<=m;j++)
- {
- if(w[i]>j) //如果装不下该物品,则不选
- f[i][j]=f[i-1][j];
- else if(w[i]<=j) //如果可以装得下,则在求max(不选,选)
- {
- if(f[i-1][j-w[i]]+v[i]>f[i-1][j]) ck[i][j]=1;
-
- f[i][j]=Math.max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
- }
- }
- }
-
- //逆向追踪最优方案
- int k=m;
- for(int i=n;i>=1;i--)
- if(ck[i][k]==1)
- {
- st[i]=1;
- k=k-w[i]; //判断减去该重量是否仍然为1
- }
-
- System.out.println("动态规划记录表如下!");
- for(int i=0;i<=n;i++)
- {
- for(int j=0;j<=m;j++)
- System.out.print(f[i][j]+" ");
- System.out.println();
- }
- System.out.println();
-
- System.out.println("物品最优选择情况如下!");
- for(int i=1;i<=n;i++) System.out.print(st[i]+" ");
- System.out.println();
-
- System.out.print("最大价值为"+f[n][m]);
-
- }
- }