[NOIP2001]装箱问题

[NOIP2001]装箱问题

题目描述

有一个箱子容量为v(正整数,o≤v≤20000),同时有n个物品(o≤n≤30),每个物品有一个体积 (正整数)。要求从 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入格式

第一行,一个整数,表示箱子容量; 第二行,一个整数,表示有n个物品; 接下来n行,分别表示这n个物品的各自体积。

输出格式

一个整数,表示箱子剩余空间。

样例输入

24
6
8
3
12
7
9
7

样例输出

0

解题思路

采用动态规划的方法,实质就是01背包问题。dp[i] [j]指在前面物品i和限制重量j的情况下的最大重量。

状态转移方程

  1. 放不下物品

    dp[i] [j]=dp[i−1] [j]

  2. 放的下物品

dp[i] [j]=max(dp[i−1] [j], dp[i−1] [j−volumes[i]]+volumes[i])

代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int v = scanner.nextInt();
        int n = scanner.nextInt();
        int[] spheres=new int[31];
        for(int i = 1; i <= n; i++) {
            spheres[i]=scanner.nextInt();
        }
       //dp[i][j]----在限制体积为v的情况下的最大体积
        int[][] dp = new int[31][20001];
        //初始化数组
       for(int i=1;i<=30;i++){
         Arrays.fill(dp[i],0);
       }

       //动态规划
        for(int i = 1; i <= n; i++) {
            for(int j = 20000; j >= 0; j--) {
                //放不下物品
                if(spheres[i]>j)
                    dp[i][j]=dp[i-1][j];
                //放不下物品
                else {
                    dp[i][j]=(dp[i-1][j]>dp[i-1][j-spheres[i]]+spheres[i]?dp[i-1][j]:dp[i-1][j-spheres[i]]+spheres[i]);
                }
            }
        }
        System.out.println(v-dp[n][v]);
    }
}
posted @ 2025-03-09 14:41  狐狸胡兔  阅读(52)  评论(0)    收藏  举报