首页 > 代码库 > (01背包)HDU - 2126 Buy the souvenirs
(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_JUDGE65 freopen("in.txt", "r", stdin);66 //freopen("out.txt", "w", stdout);67 #endif68 //iostream::sync_with_stdio(false);69 solve();70 return 0;71 }
(01背包)HDU - 2126 Buy the souvenirs
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。