题目友链☟
洛谷标签:
动
态
规
划
,
递
归
,
N
O
I
p
普
及
组
2001
(
或
之
前
)
动态规划,递归,NOIp普及组2001(或之前)
动态规划,递归,NOIp普及组2001(或之前)
但我觉得,还是可以分为搜索与回溯
题目描述
有一个箱子容量为 V V V(正整数, 0 ≤ V ≤ 20000 0 ≤V≤20000 0≤V≤20000),同时有 n n n个物品( 0 < 300 < n ≤ 30 0<300<n≤30 0<300<n≤30),每个物品有一个体积(正整数)。
要求 n n n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入输出格式
输入格式:
1
1
1个整数,表示箱子容量
1
1
1个整数,表示有
n
n
n个物品
接下来
n
n
n行,分别表示这
n
n
n个物品的各自体积
输出格式:
1
1
1个整数,表示箱子剩余空间。
输入输出样例
输入样例# 1 1 1:
24
6
8
3
12
7
9
7
输出样例# 1 1 1:
0
解析:
也许很多大佬都觉得,这种题目应该用动态规划来做,但是我写一个搜索的题解(不要问为什么,因为我蒟)。。。
这个题目其实是有点像01背包的。
在搜索中定义一个
s
u
m
sum
sum,用来储存现在的箱子剩余体积,到时候可以拿总量去减(逆向思维)既然有了这个这个
s
u
m
sum
sum,出口就好找了,定义
a
n
s
ans
ans(一开始为零(初始化,不多说)),当
a
n
s
ans
ans<总体积减去
s
u
m
sum
sum时,
a
n
s
ans
ans就等于这个值。每次都进行这个搜索,如果有某一个物品的体积≤
s
u
m
sum
sum时,就拿sum去减即可。输出的时候要注意,不是仅仅输出
a
n
s
ans
ans,而是用总重-
a
n
s
ans
ans,就可以完美结束了。
下面,就该上代码了:
#include<iostream>
using namespace std;
int a[1001];
int n,c,ans;//ans表示已经用完的空间
void s(int x,int sum){//定义两个值,一个表示当前箱子剩余体积,一个记数
if (x==n+1){
if (ans<c-sum)
ans=c-sum;//当ans<总数-剩余体积时,ans就有值了
return;
}
else
{
s(x+1,sum);//下一次搜索
if (a[x]<=sum)
s(x+1,sum-a[x]);
}
}
int main(){
cin>>c>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
ans=0;//初始化
s(1,c);//从总体积开始搜起
cout<<c-ans<<endl;//上面说过的,注意这里
return 0;
}
不要老是Ctrl + C 和Ctrl + V啦
如有雷同,纯属巧合!