【HDU 1114 & POJ 1384】 完全背包(注意技巧)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114
题目大意:给你一个体积为V的猪猪存钱罐,然后有一些体积为c,价值为w的硬币,问你如何装硬币能使总价值最大。
解题思路:
这题有两点错误很容易犯。 第一:用了01背包而不是完全背包。 第二:初始化问题还没搞清楚(这里的初始化指的是不同类型的最大值初始化的条件不一样)
1、题目给你的硬币数量没规定只能取一次,能取多次当然就是完全背包了,当然也有可能是多重背包,这里不讨论。
2、重点在第二点了。背包进行初始化时,如果恰好完全装满,则dp[0]赋值为0,其余赋值为无穷。如果只希望价值最大,则初始化时将dp[0~V]都赋值为0。
本题是恰好完全装满,因为不装满不可能知道有很多钱钱啦,当然也就不不可能打破存钱罐。
1 #include <iostream> 2 #include <math.h> 3 using namespace std; 4 5 const int maxn = 100005 ; 6 #define min(x1,y1) x1<y1?x1:y1 7 int c[maxn], w[maxn], dp[maxn] ; 8 const int DNF = 99999999; 9 10 int main() 11 { 12 int T, E, F, V, N; 13 cin >> T ; 14 while(T--) 15 { 16 cin >> E >> F ; 17 V = F - E ; 18 cin >> N ; 19 // memset(dp,0,sizeof(dp)); 20 dp[0]=0; 21 for(int i=1; i<=V; i++) 22 dp[i]=DNF; 23 for(int i=1; i<=N; i++) 24 cin >> w[i] >> c[i] ; 25 for(int i=1; i<=N; i++) 26 for(int j=c[i]; j<=V; j++) // 每件物品可以选无限件 所以必须 O~v ,如果只能选一次那么 V~0 27 dp[j]=min(dp[j],dp[j-c[i]]+w[i]); 28 if(dp[V]!=DNF) 29 cout << "The minimum amount of money in the piggy-bank is " << dp[V] <<"."<< endl ; 30 else 31 cout << "This is impossible." << endl ; 32 } 33 return 0; 34 }