问题 B: 【动态规划】简单背包问题II
时间限制: 1 Sec 内存限制: 64 MB提交: 21 解决: 14
[提交][状态][讨论版]
题目描述
张琪曼:“为什么背包一定要完全装满呢?尽可能多装不就行了吗?”
李旭琳:“你说得对,这和墨老师曾告诉我们的‘日中则昃,月满则亏’是一个道理。”所以,现在的问题是,她们有一个背包容量为v(正整数,0≤v≤20000),同时有n个魔法石(0≤n≤30),每个魔法石有一个体积 (正整数)。要求从n个魔法石中,任取若干个装入包内,使背包的剩余空间为最小。
李旭琳:“你说得对,这和墨老师曾告诉我们的‘日中则昃,月满则亏’是一个道理。”所以,现在的问题是,她们有一个背包容量为v(正整数,0≤v≤20000),同时有n个魔法石(0≤n≤30),每个魔法石有一个体积 (正整数)。要求从n个魔法石中,任取若干个装入包内,使背包的剩余空间为最小。
输入
第一行为一个整数,表示背包容量,第二行为一个整数,表示有n个魔法石,接下来n行,分别表示这n个魔法石的各自体积。
输出
只有一个整数,表示背包剩余空间。
样例输入
24
6
8
3
12
7
9
7
样例输出
0
代码:
1 #include<cstdio> 2 #include <iostream> 3 #include <cstring> 4 5 using namespace std; 6 7 int dp[35][20005]; 8 9 int main(){ 10 int T; 11 int M; 12 int t[20005]; 13 int p[20005]; 14 while(scanf("%d %d",&T,&M)!=EOF){ 15 for(int i=0;i<=M;i++){ 16 for(int j=0;j<=T;j++){ 17 dp[i][j]=0; 18 } 19 } 20 dp[0][0]=0; 21 for(int i=1;i<=M;i++){ 22 scanf("%d",&t[i]); 23 } 24 for(int i=1;i<=M;i++){ 25 for(int j=1;j<=T;j++){ 26 if(j>=t[i]){ 27 dp[i][j]=max(dp[i-1][j],dp[i-1][j-t[i]]+t[i]); 28 }else{ 29 dp[i][j]=dp[i-1][j]; 30 } 31 } 32 } 33 34 printf("%d ",T-dp[M][T]); 35 } 36 return 0; 37 }