[NOIP普及组2011]装箱问题

文章目录

  • 链接
    • 博客链接
    • 题目链接
  • 题目内容
    • 题目描述
    • 格式
      • 输入
      • 输出
  • 样例
      • 输入
      • 输出
  • 前缀知识
  • 题解

题目名称:装箱问题
来源:2011年NOIP普及组

链接

博客链接

  • 博客园
  • 洛谷博客

题目链接

  • Vijos 题目 递交 讨论 题解
  • 洛谷(P1049) 题目 提交代码 提交记录 讨论列表 查看题解

题目内容

题目描述

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

格式

输入

1 1 1个整数,表示箱子容量

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

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

输出

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

样例

输入

24
6
8
3
12
7
9
7

输出

0

前缀知识

  • 01背包

题解

这是一道01背包裸题,先进行01背包,在找到比 v v v小但是可以得到的数,输出 v v v与这个数的差。

//C++
#include
#include
#include
#define downto(name,i,u,d) for(name i=u;i>=d;i--)
inline void output(long long o); 
inline long long input();
std::bitset<20001>full;
int main(){
	short v=input(),n=input(),volume;
	full[0]=true;
	while(n--){
	    volume=input();
	    downto(short,i,v,volume)full[i]=full[i]|full[i-volume];
	}for(short i=0;;i++)
	if(full[v-i])return output(i),0;
}inline void output(long long o){
	if(o<0)putchar('-'),o=-o;
	if(o>=10)output(o/10);
	putchar(o%10^'0');
}inline long long input(){
	bool minus=false;
	char now=getchar();
	long long i=0;
	for(;!isdigit(now);now=getchar())
	if(now=='-')minus=!minus;
	for(;isdigit(now);now=getchar())i=(i<<3)+(i<<1)+(now^'0');
	return minus?-i:i;
}
//pascal
type box=0..20000;
var
    i,n:1..30;
    j,v,volume:box;
    full:array[box] of boolean;
begin
    readln(v);
    readln(n);
    full[0]:=true;
    for j:=1 to v do full[j]:=false;
    for i:=1 to n do begin
        readln(volume);
        for j:=v downto volume do full[j]:=full[j] or full[j-volume];
    end;for j:=0 to v do
    if full[v-j] then break;
    write(j);
end.

你可能感兴趣的:(01背包,2011,NOIP,普及组)