(01背包)HDU - 2126 Buy the souvenirs
Posted tak_fate
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(01背包)HDU - 2126 Buy the souvenirs相关的知识,希望对你有一定的参考价值。
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126
题意:给n个物品,和m块钱,输出最多物品个数和其方案数。
委屈:求出最多物品个数就是一个裸的01背包,但是同时求出方案数,难住了我。
想了半天,感觉可以一波dp求出来,但是又想不明白状态是怎么表示和转移的。
无奈就先写个dfs提交试一发,果断超时了。
最后无奈看了题解,只能说,01背包还是不会。
其实与其说01背包不会不如说动态规划不会,感觉好难。
感觉自己好lowbee啊。。
感觉碰到dp就萎了。
1、想不出状态转移方程
2、搞不清循环的顺序
3、定不了正确的边界
好垃圾啊我。。
分析:在dp上加一维,dp[][0]表示原本的背包,dp[][1]表示方案个数。
把每个物品的价值看成1。
当当前的物品选择取时:
如果总价值和不取一样多,说明两种不同的总花费得到了相同的价值,这个时候,方案数应该想加起来。
if (dp[j][0]==dp[j-cost[i]][0]+1) dp[j][1]=dp[j-cost[i]][1]+dp[j][1];
如果总价值比不取多,说明在原总价值的基础上产生了新的花费方案,但是这些方案继承于取前的方案,所以方案数不变。
1 else if (dp[j][0] < dp[j-cost[i]][0]+1) { 2 dp[j][0]=dp[j-cost[i]][0]+1; 3 dp[j][1]=dp[j-cost[i]][1]; 4 }
代码:
1 #include <set> 2 #include <map> 3 #include <list> 4 #include <cmath> 5 #include <queue> 6 #include <vector> 7 #include <bitset> 8 #include <string> 9 #include <cctype> 10 #include <cstdio> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 16 using namespace std; 17 18 typedef long long ll; 19 typedef unsigned long long ull; 20 #define inf (0x3f3f3f3f) 21 #define lnf (0x3f3f3f3f3f3f3f3f) 22 #define eps (1e-8) 23 int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} 24 25 //-------------------------- 26 27 int t; 28 int cost[40]; 29 int dp[510][2]; 30 int n,m; 31 32 void solve(){ 33 scanf("%d",&t); 34 while(t--){ 35 scanf("%d%d",&n,&m); 36 for(int i=0;i<n;i++){ 37 scanf("%d",&cost[i]); 38 } 39 memset(dp,0,sizeof(dp)); 40 for(int i=0;i<=m;i++){ 41 dp[i][1]=1; 42 } 43 for(int i=0;i<n;i++){ 44 for(int j=m;j>=cost[i];j--){ 45 if (dp[j][0]==dp[j-cost[i]][0]+1) 46 dp[j][1]=dp[j-cost[i]][1]+dp[j][1]; 47 else if (dp[j][0] < dp[j-cost[i]][0]+1) { 48 dp[j][0]=dp[j-cost[i]][0]+1; 49 dp[j][1]=dp[j-cost[i]][1]; 50 } 51 } 52 } 53 if(dp[m][0]==0)puts("Sorry, you can‘t buy anything."); 54 else printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n",dp[m][1],dp[m][0]); 55 } 56 } 57 58 59 60 61 62 int main() { 63 64 #ifndef ONLINE_JUDGE 65 freopen("in.txt", "r", stdin); 66 //freopen("out.txt", "w", stdout); 67 #endif 68 //iostream::sync_with_stdio(false); 69 solve(); 70 return 0; 71 }
以上是关于(01背包)HDU - 2126 Buy the souvenirs的主要内容,如果未能解决你的问题,请参考以下文章