【题解】【动态规划】—— [NOIP2001 普及组] 装箱问题
前置知识:动态规划01背包问题模型。
[NOIP2001 普及组] 装箱问题
题目描述
有一个箱子容量为 V V V,同时有 n n n 个物品,每个物品有一个体积。
现在从 n n n 个物品中,任取若干个装入箱内(也可以不取),使箱子的剩余空间最小。输出这个最小值。
输入格式
第一行共一个整数 V V V,表示箱子容量。
第二行共一个整数 n n n,表示物品总数。
接下来 n n n 行,每行有一个正整数,表示第 i i i 个物品的体积。
输出格式
- 共一行一个整数,表示箱子最小剩余空间。
输入输出样例
输入 #1
24
6
8
3
12
7
9
7
输出 #1
0
提示
对于 100 % 100\% 100% 数据,满足 0 < n ≤ 30 0<n \le 30 0<n≤30, 1 ≤ V ≤ 20000 1 \le V \le 20000 1≤V≤20000。
【题目来源】
NOIP 2001 普及组第四题
1.题意解析
这道题可以直接套用动态规划01背包问题模型。想要让剩余空间最小,就要让利用空间最大。
我们可以将重量看成总价值,然后套用01背包问题模型求解就行了。
2.AC代码
2.1.二维 d p dp dp
#include<bits/stdc++.h>
using namespace std;
int main()
{
//dp[j]表示当前放i个物品,上限为j时能达到的最大重量
int v,n,a[40],dp[40][20010]={};
cin>>v>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
for(int j=1;j<=v;j++)//注意要从后往前枚举
//状态转移方程,每一个物品都可以选择放或不放
if(j>=a[i])
dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i]]+a[i]);
else
dp[i][j]=dp[i-1][j];
cout<<v-dp[n][v];//一定要用总重量减去最大重量
return 0;
}
2.2.一维 d p dp dp
#include<bits/stdc++.h>
using namespace std;
int main()
{
//dp[j]表示当前放i个物品,上限为j时能达到的最大重量
int v,n,a[40],dp[20010]={};
cin>>v>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
for(int j=v;j>=a[i];j--)//注意要从后往前枚举
//状态转移方程,每一个物品都可以选择放或不放
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
cout<<v-dp[v];//一定要用总重量减去最大重量
return 0;
}
喜欢就订阅此专辑吧!
【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。
欢迎扫码关注蓝胖子编程教育