原题链接
题目大意
有一个箱子和
n
n
n个物品,每个物品都有各自的体积,求出放入物品后,箱子里最少还有多少是空的。
S
a
m
p
l
e
\mathbf{Sample}
Sample
I
n
p
u
t
\mathbf{Input}
Input
24 一个整数,表示箱子容量
6 一个整数,表示有n个物品
8 接下来n行,分别表示这n 个物品的各自体积
3
12
7
9
7
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
0
H
i
n
t
&
E
x
p
l
a
i
n
\mathbf{Hint\&Explain}
Hint&Explain
取第二件,第三件,第四件物品,容量和为8+3+12=24
,剩余容量为24-24=0
。
解题思路
这题有两种做法,一种是
d
f
s
dfs
dfs,一种是
d
p
dp
dp。
①
d
f
s
dfs
dfs
d
f
s
dfs
dfs遍历所有物品,最后用总容量减去结果容量即可,注意
d
f
s
dfs
dfs出来的结果一定
≤
\le
≤箱子容量。
代码在下面:
#include<iostream>
#include<cmath>
using namespace std;
const int maxn=30+10;
int n,m,a[maxn],res=0x7fffffff;
void dfs(int hea,int k)
{
if(hea>m) return;
if(k==n+1)
{
res=std::min(res,m-hea);
return;
}
dfs(hea,k+1);
dfs(hea+a[k],k+1);
}
int main()
{
cin>>m>>n;
for(int i=1; i<=n; i++) cin>>a[i];
dfs(0,1);
cout<<res<<endl;
return 0;
}
②
d
p
dp
dp
就是普普通通的
01
01
01背包,只不过价值就是重量而已。
设
d
p
j
dp_{j}
dpj为钱数为
j
j
j时可以拿到的最大价值,
w
i
w_i
wi为
i
i
i物品的重量,即:
d
p
j
=
{
0
j
=
0
m
a
x
(
d
p
j
,
d
p
j
−
w
i
+
w
i
)
1
≤
i
≤
n
,
w
i
≤
j
≤
m
dp_{j}= \begin{cases} 0&j=0 \\max(dp_{j},dp_{j-w_i}+w_i)&1\le i\le n,w_i\le j\le m \end{cases}
dpj={0max(dpj,dpj−wi+wi)j=01≤i≤n,wi≤j≤m
答案就是
m
−
d
p
m
m-dp_m
m−dpm
上代码
#include<iostream>
using namespace std;
int n,m;
int w[35],c[35];
int dp[20010];
int main()
{
cin>>m>>n;
for(int i=1; i<=n; i++) cin>>w[i],c[i]=w[i];
for(int i=1; i<=n; i++)
{
for(int j=m; j>=w[i]; j--)
{
dp[j]=std::max(dp[j],dp[j-w[i]]+c[i]);
}
}
cout<<m-dp[m]<<endl;
return 0;
}
完美切题 ∼ \sim ∼