背包型动态规划-1014 装箱问题 2001年NOIP全国联赛普及组

博客目录

1014 装箱问题

 

2001年NOIP全国联赛普及组

时间限制: 1 s    空间限制: 128000 KB      题目等级 : 黄金 Gold

 

题目描述 Description

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

输入描述 Input Description

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

输出描述 Output Description

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

样例输入 Sample Input

24
6
8
3
12
7
9
7

样例输出 Sample Output

0

一、分类

动态规划,01背包问题

二、思路

1.状态转移方程

设arr[i][j] 为:考虑前i个物品时,背包容量为v个体积时,最少的剩余空间。

考虑第i个物品,若体积大于背包,则放不进箱子。若体积小于背包,则产生两种情况,1.放  2.不放,比较两种状态取最小值。

设j为体积,i 为考虑前i个箱子

不放时,最小剩余容量为arr[i-1][j];  放时,最小剩余容量为arr[i-1][j-co[i]],,co[i]为第i个箱子的体积。

        arr[i][j]=MIN(arr[i-1][j],arr[i-1][j-co[i]]);     ,co[i]<=j       // min(不放,放),第i个箱子能够放入

        arr[i][j]=arr[i-1][j];                                      ,co[i]>j       //j体积时 第i个箱子不能放入,即剩余体积等于前i-1个箱子j体积时的最优解

2.初始化

考虑前0个物品时,最少的剩余空间 = 背包容量 。即arr[0][i]=i, 0<=i<=v

3.答案

输出结果应为arr[n][v],即考虑全体积和所有箱子时的最优解

三、AC代码

#include
#define MIN(a,b) ((a)>(b)?(b):(a))
int arr[40][30000]={0};
int co[40];
int main()
{                //经典dp,01背包 
    int v;
    int n;
    scanf("%d %d",&v,&n);
    int i;
    for(i=1;i<=n;i++)
    {
        scanf("%d",co+i);
    }
    int j;

    for(i=1;i<=v;i++)
    {
        arr[0][i]=i;
    }
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=v;j++)
        {
            if(j>=co[i])
            {
                arr[i][j]=MIN(arr[i-1][j],arr[i-1][j-co[i]]);
            }
            else 
                arr[i][j]=arr[i-1][j];
        }
    }
    printf("%d",arr[n][v]);
}



你可能感兴趣的:(动态规划dp)