请勿原模原样复制!
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]);
}
}