题目描述 Description
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入描述 Input Description
一个整数v,表示箱子容量
一个整数n,表示有n个物品
接下来n个整数,分别表示这n 个物品的各自体积
输出描述 Output Description
一个整数,表示箱子剩余空间。
样例输入 Sample Input
24
6
8
3
12
7
9
7
样例输出 Sample Output
0
解题思路:
这几天打算开始撸dp了,先从code[vs]上最为简单的dp开始打吧,一道一道耐心写总结,写方法,慢慢体会,听知乎上说,没有100+的dp题,是根本不能理解dp的本质的,目前我只了解到了最为关键的几个地方,也就是我们常说的 状态和 状态转移方程,状态转移方程就是状态间转移的方程,NM,这不是废话么?哈哈,,所说的状态是子状态之间的转移了。而对于所有的dp问题,都可以归结为对于状态的定义和对于状态转移方程的求解了。
对于这道题我们定义的状态是:f[j],表示加到第j件物品后的最大体积
状态转移方程:f[j] = max{ f[j],f[j-w[i]+w[i] };
代码:
# include<cstdio> # include<iostream> # include<cstring> # include<algorithm> using namespace std; int w[33]; int f[20005]; int main(void) { int V,n; cin>>V>>n; memset(f,0,sizeof(f)); for( int i = 1;i <= n;i++ ) cin>>w[i]; for( int i = 1;i <= n;i++ ) { for( int j = V;j >= w[i];j-- ) { f[j]=max(f[j],f[j-w[i]]+w[i]);//f[j]表示装到第j个物的最大体积 } } cout<<V-f[V]<<endl; return 0;
}