您的位置:首页 > 其它

【动态规划入门】装箱问题

2017-03-26 14:41 537 查看
1014 装箱问题

2001年NOIP全国联赛普及组

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

题目描述 Description

有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。

要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入描述 Input Description

一个整数n,表示有n个物品

接下来n个整数,分别表示这n 个物品的各自体积

输出描述 Output Description

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

样例输入 Sample Input

24

6

8

3

12

7

9

7

样例输出 Sample Output

0

链接:http://codevs.cn/problem/1014/

动态规划入门相关资料:http://www.hawstein.com/posts/dp-novice-to-advanced.html

解题思路:

动态规划的核心思想就是将问题划分为n个存在共同子问题的子问题,并将这些子问题的结果计算并存储起来,一般为数组。

本题使用一维数组dp来记录在当前空间下的最大填充体积,dp[j] ->在体积为j的情况下最大填充为dp[j];由于在对一个物体来说,它有两种状态,放入箱子dp[i-num[j]]+num[j],或者不放入dp[j],我们需要的是这两者中的较大的一个,即:dp[j] = max(dp[j],dp[i-num[j]]+num[j]);

对于dp[i-num[j]]的解释可以参考动态规划:从新手到专家 中状态相关介绍

代码:

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

int main()
{
int n,m;
cin >> n >> m;
int num[40] = {0};//记录每个物体的体积,要求30就可以,习惯开大点
int dp[20005] = {0};//记录在j下最大体积V,要求是20000
for(int i = 0; i < m; i++)//输入
cin >> num[i];
for(int i = 0; i < m;i++)//将给出的物体放入箱子,防止重复计算
{
for(int j = n; j >= num[i]; j--)//判断物体是否放入箱子
{
dp[j] = max(dp[j],dp[j-num[i]]+num[i]);
}
}
cout < <n - dp
<<endl;
return 0;
}


这道题中比较技巧的就是那两层for循环,外面那一层的目的是将给出的物体体积一个一个去进行比较,比如第一个物体体积是4,从n到4,所有的dp[j]都会变成4,得到了当填入4时所有子问题(在容量为j时最大填充量)的值

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: