经典模型 动态规划(dp数组)

    科技2022-07-10  166

    由经典的 01背包问题 入手 已知:背包最大容积pack_max ,物品总数thing_max(每件物品的体积tiji ,价值val)求解:背包可装入物品的总的最大价值是多少

    思路: 子问题:第j体积状态(小于或等于)下最大价值=第j -1体积状态下第i件物品的可装入或者不可装入两种情况中的最大值

    public class 背包问题 { static Thing[] things ; static int[] dp ; public static void main(String[] args) { //记录输入 Scanner sc = new Scanner(System.in); int pack_max =sc.nextInt(); //背包体积最大值 int thing_max =sc.nextInt(); //物品总数 things =new Thing[thing_max +1]; dp =new int[pack_max +1]; //初始化每一种体积状态下的价值为‘0’ for(int i =1 ;i <=thing_max ;i ++) {things[i] =new Thing(sc.nextInt() ,sc.nextInt());} sc.close(); //递推遍历所有物品 for(int i =1 ;i <=thing_max ;i ++) { for(int j =pack_max ;j >=things[i].tiji ;j --) //子问题分解,倒序遍历,保证dp[j]均只被修改一次 //转移方程 dp[j] =Math.max(dp[j], dp[j -things[i].tiji] +things[i].val); } //输出结果 System.out.println(dp[pack_max]); } } class Thing{ int tiji; //体积 int val; //价值 public Thing(int tiji, int val) { super(); this.tiji = tiji; this.val = val; } } 完全背包问题 已知:普通背包问题条件下,每i件物品的数量都可以是多个的(可视为物品总数是无限多的)求解:背包最大的总的价值

    思路: 重复遍历第i件物品->dp[j]应实时修改以取得最大值

    public class 完全背包 { static Thing[] things ; static int[] dp ; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int pack_max =sc.nextInt(); int thing_max =sc.nextInt(); things =new Thing[thing_max +1]; dp =new int[pack_max +1]; for(int i =1 ;i <=thing_max ;i ++) {things[i] =new Thing(sc.nextInt() ,sc.nextInt());} sc.close(); for(int i =0 ;i <=thing_max ;i ++) dp[i] =0; for(int i =1 ;i <=thing_max ;i ++) { for(int j =things[i].tiji ;j <=pack_max ;j ++) //正序遍历物品,dp[j]将被实时修改为j体积状态下的最大值 dp[j] =Math.max(dp[j], dp[j -things[i].tiji] +things[i].val); } System.out.println(dp[pack_max]); } }

    参考: 简单的动规实现案例-三角形 背包问题 王国的故事-动规的实现需要考虑的要素

    Processed: 0.010, SQL: 8