题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2844

题意:一位同学想要买手表,他有n种硬币,每种硬币已知有num[i]个。已知手表的价钱最多m元,问她用这些钱能够凑出多少种价格来买手表。

分析:二进制优化的多重背包,假设每种硬币为容量为val[i]且价值也为val[i]的物品,最后有dp[i]==i则能组成价格为i。因为容量为i能达到的最大价值也是i,刚好符合01背包的含义。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <queue>
  7. #include <cstdlib>
  8. #include <stack>
  9. #include <vector>
  10. #include <set>
  11. #include <map>
  12. #define LL long long
  13. #define mod 1000000007
  14. #define inf 0x3f3f3f3f
  15. #define N 100010
  16. using namespace std;
  17. int dp[N],val[],num[],a[N];
  18. int n,m,tot;
  19. int solve()
  20. {
  21. for(int i=;i<=m;i++)dp[i]=;
  22. for(int i=;i<tot;i++)
  23. {
  24. for(int j=m;j>=a[i];j--)
  25. dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
  26. }
  27. int sum=;
  28. for(int i=;i<=m;i++)if(dp[i]==i)sum++;
  29. return sum;
  30. }
  31. int main()
  32. {
  33. while(scanf("%d%d",&n,&m)&&(n+m))
  34. {
  35. for(int i=;i<=n;i++)scanf("%d",&val[i]);
  36. for(int i=;i<=n;i++)scanf("%d",&num[i]);
  37. tot=;
  38. for(int i=;i<=n;i++)
  39. {
  40. for(int j=;j<=num[i];j*=)
  41. {
  42. a[tot++]=val[i]*j;
  43. num[i]-=j;
  44. }
  45. if(num[i])a[tot++]=num[i]*val[i];
  46. }
  47. int ans=solve();
  48. printf("%d\n",ans);
  49. }
  50. }

这题由于数据量较大,就算是二进制优化的多重背包也是998ms险过。这里可以增加一个一维数组use[ i ],记录到达i元时第j种钱用的次数。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <queue>
  7. #include <cstdlib>
  8. #include <stack>
  9. #include <vector>
  10. #include <set>
  11. #include <map>
  12. #define LL long long
  13. #define mod 1000000007
  14. #define inf 0x3f3f3f3f
  15. #define N 100010
  16. using namespace std;
  17. int dp[N],val[],num[],used[N];//i元钱时某种钱用的次数
  18. int n,m;
  19. int solve()
  20. {
  21. int sum=;
  22. for(int i=;i<=m;i++)dp[i]=;
  23. dp[]=;
  24. for(int i=;i<=n;i++)
  25. {
  26. memset(used,,sizeof(used));//每次初始化第i种钱用了0次
  27. for(int j=val[i];j<=m;j++)
  28. {
  29. if(!dp[j]&&dp[j-val[i]]&&used[j-val[i]]<num[i])//到达j元用的i种钱的次数是到达 j-val[i]元用的次数加1
  30. {
  31. dp[j]=;used[j]=used[j-val[i]]+;sum++;
  32. }
  33. }
  34. }
  35. return sum;
  36. }
  37. int main()
  38. {
  39. while(scanf("%d%d",&n,&m)&&(n+m))
  40. {
  41. for(int i=;i<=n;i++)scanf("%d",&val[i]);
  42. for(int i=;i<=n;i++)scanf("%d",&num[i]);
  43. int ans=solve();
  44. printf("%d\n",ans);
  45. }
  46. }

hdu2844(多重背包)的更多相关文章

  1. HDU2844买表——多重背包初探

    HDU2844买表多重背包问题题目大意都不大好懂,是利用手头上的硬币看看能组合出多少种价格,也就是跑完背包,看看有多少背包符合要求 剩下的就是多重背包的问题了1.第一个处理办法就是直接当01背包进行存 ...

  2. HDU-2844 Coins(多重背包)

    Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...

  3. hdu2844 &amp; poj1742 Coin ---多重背包--两种方法

    意甲冠军:你有N种硬币,每个价格值A[i],每个号码C[i],要求. 在不超过M如果是,我们用这些硬币,有多少种付款的情况下,.那是,:1,2,3,4,5,....,M这么多的情况下,,你可以用你的硬 ...

  4. 假期训练六(poj-1753,递归+hdu-2844,多重背包)

    题目一:传送门 题意:有一个4*4的棋盘,每次翻转一个棋子和它的上下左右的四个棋子,判断翻转多少次之后可以变为纯色的棋盘. 思路:总共有C(0,16)+C(1,16)+C(2,16)+……+C(16, ...

  5. HDU2844 Coins 多重背包

    Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. HDU2844 Coins(多重背包)

    多重背包就是每种物品有数量限制时求解最大价值. 如果一种物品数量和重量之积超过背包容量,可视为完全背包:其余情况通过二进制拆分,将几个数量的物品看成一个,转化为01背包求解. 按照这种思路代码是这样的 ...

  7. 多重背包的入门题目HDU1171,2191,2844.

    首先,什么叫多重背包呢? 大概意思就是:一个背包有V总容量,有N种物品,其价值分别为Val1,Val2--,Val3,体积对应的是Vol1,Vol2,--,Vol3,件数对应Num1,Num2--,N ...

  8. 洛谷P1782 旅行商的背包[多重背包]

    题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...

  9. HDU 2082 找单词 (多重背包)

    题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...

随机推荐

  1. EasyUI - Tabs 选项卡标签

    基本效果: 效果图: html代码: <div id="tab"> <div title="tab1" > <p>tab1& ...

  2. Fedora 17 下安装codeblocks

    Fedora 17 下安装codeblocks:        1.直接从yum源安装:        sudo yum install codeblocks        2.源码安装        ...

  3. SQL SERVER之数据查询

     本篇主要解说查询语句,全部的演示样例都会依照以下这张表进行. stuID stuName age sex 11090241031 王小虎 21 男 11090241032 王小六 22 男 11 ...

  4. 构建基于Jenkins + Github的持续集成环境

    搭建持续集成首先要了解什么是持续集成,带着明确的目标去搭建持续集成环境才能让我们少走很多弯路.持续集成(Continuous integration)简称CI,是一种软件开发的实践,可以让团队在持续集 ...

  5. Irvine的专业汇编网站

    http://asmirvine.com/ http://download.csdn.net/download/stupid_boy2007/3890853 http://download.csdn. ...

  6. spring mvc controller json数据

    项目中遇到个批处理,需要前台传递一个json格式对象数组,如下:var data={   "wos":[{"id":1,"satisfaction&q ...

  7. hdu 4687 Boke and Tsukkomi

    Dancing link twice. Find the maximum combination numbers in the first time. Enumerate each node, dan ...

  8. 2014 Multi-University Training Contest 1 — D. Task

    题目链接:pid=4864">http://acm.hdu.edu.cn/showproblem.php?pid=4864 题目大意: 有N个机器.M个任务. 当中每一个机器有xi,y ...

  9. css怎样使顶端悬浮导航栏不遮住下面一层页面内容

    在两个层之间加这个<span class="blank" style="height:20px;"></span>,其中高度可以自己设置 ...

  10. Windows的自带控件(比如TButton)大多数消息都由它自己处理,Delphi覆盖了那么多WM_函数优先级较低,一般用不上

    在空窗体上放一个TButton,一个TPanel,然后把在TWinControl.WMEraseBkgnd里下断点: procedure TWinControl.WMEraseBkgnd(var Me ...