hdu 2844 混合背包【背包dp】

http://acm.hdu.edu.cn/showproblem.php?pid=2844

题意:有n种纸币面额(a1,a2,...an),每种面额对应有(c1,c2,...cn)张。问这些钱能拼成1-m中多少种值。

题解:背包dp问题。若ci=1,是01背包,若ci*ai>=m则是完全背包,否则是多重背包。(详见《背包九讲》)

先复习一下三种简单背包形式:

 01背包(F[v] ← max{F[v], F[v ?Ci] +Wi} ):

 

  

 完全背包(F[i, v] = max(F[i ? 1, v], F[i, v ?Ci] +Wi)):

  

 多重背包(利用二进制思想转化为01背包):

  

利用三种背包形式就可以轻松解决此题:

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<vector>
 6 using namespace std;
 7
 8 int f[100005];
 9 int c[105],a[105];
10 int n,m;
11
12 void ZeroOnePack(int w,int v)
13 {
14     for(int j=m;j>=v;j--)
15         f[j]=max(f[j],f[j-w]+v);
16 }
17
18 void CompletePack(int w,int v)
19 {
20     for(int j=v;j<=m;j++)
21         f[j]=max(f[j],f[j-w]+v);
22 }
23
24 void MultiplePack(int w,int v,int c)
25 {
26     int k=1;
27     while(k<c)
28     {
29         ZeroOnePack(k*w,k*v);
30         c=c-k;k*=2;
31     }
32     ZeroOnePack(c*w,c*v);
33 }
34
35 int main()
36 {
37     while(scanf("%d%d",&n,&m)==2)
38     {
39         memset(f,0,sizeof(f));
40         if(n==0) break;
41         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
42         for(int i=1;i<=n;i++) scanf("%d",&c[i]);
43         for(int i=1;i<=n;i++){
44             if(c[i]==1)
45                 ZeroOnePack(a[i],a[i]);
46             else if(c[i]*a[i]>=m)
47                 CompletePack(a[i],a[i]);
48             else
49                 MultiplePack(a[i],a[i],c[i]);
50         }
51         int ans=0;
52         for(int i=1;i<=m;i++)
53             if(f[i]==i) ans++;
54         printf("%d\n",ans);
55     }
56     return 0;
57 }

原文地址:https://www.cnblogs.com/zxhyxiao/p/8407222.html

时间: 2024-09-30 05:50:45

hdu 2844 混合背包【背包dp】的相关文章

HDU 2844 Coins (组合背包)

题意   给你n种面额不同的金币和每种金币的个数  求这些金币能组合成的面额在m内有多少种 还是明显的背包问题  d[i]表示这些金币在i内能组合成的最大面额  初始化d为负无穷  d[0]=0  这样就可以保证d[i]恰好为i时才能为正值 原因可以自己想想  然后就用背包背吧  直接多重背包也可以过  但是分成多重背包和完全背包要快一点 #include<cstdio> #include<cstring> #include<algorithm> using names

HDU 2844 混合背包、

题意:一个人想买手表,给你n个价值的硬币,然后给你n个价值硬币对应的个数.但是呢,这个人只知道这个手表的价格不超过m元.问他最多能买多少种价值的手表 思路:dp背包专题 但是- - 一直不知道该怎么dp 终于想通了. PS:对于背包dp说一说自己的理解吧(虽然不知道有什么用) 一旦涉及到dp 你就要考虑dp数组里面存的是什么,另外一维数组的话你就要考虑dp[i]中,那个i代表的是什么,同理二维数组也是一样.  然后写出状态转移方程,你的状态转移方程一定要和你dp数组里面存的状态是相一致的. 1

HDU 2844 Coins (多重背包计数 空间换时间)

Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8999    Accepted Submission(s): 3623 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One

HDu -2844 Coins多重背包

这道题是典型的多重背包的题目,也是最基础的多重背包的题目 题目大意:给定n和m, 其中n为有多少中钱币, m为背包的容量,让你求出在1 - m 之间有多少种价钱的组合,由于这道题价值和重量相等,所以就是dp[i] = i, 其中dp[i]表示当前背包容量为i 的时候背包能装的价值. 题目思路: 模板 二进制优化 话说那个二进制真的很奇妙,只需要2的1次方 到 2的k-1次方, 到最后在加上一项当前项的个数 - 2 的k次方 + 1,也就是这些系数分别为1; 2; 22 .....2k-1;Mi

hdu 2844 Coins 多重背包模板题 ,二进制优化。据说是楼教主的男人八题之一

Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8052    Accepted Submission(s): 3291 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One

HDU 2844 Coins 多重背包(二进制优化)

点击打开链接 Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8167    Accepted Submission(s): 3327 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dolla

HDU - 2844 Coins(多重背包+完全背包)

题意 给n个币的价值和其数量,问能组合成\(1-m\)中多少个不同的值. 分析 对\(c[i]*a[i]>=m\)的币,相当于完全背包:\(c[i]*a[i]<m\)的币则是多重背包,考虑用二进制优化解决.最后扫一遍\(dp[i]\)统计答案. import java.util.*; import java.math.*; public class Main{ static int MAXN = 100005; static int []dp = new int[MAXN]; static i

背包系列练习( hdu 2844 Coins &amp;&amp; hdu 2159 &amp;&amp; poj 1170 Shopping Offers &amp;&amp; hdu 3092 Least common multiple &amp;&amp; poj 1015 Jury Compromise)

作为一个oier,以及大学acm党背包是必不可少的一部分.好久没做背包类动规了.久违地练习下-.- dd__engi的背包九讲:http://love-oriented.com/pack/ 鸣谢http://blog.csdn.net/eagle_or_snail/article/details/50987044,这里有大部分比较有趣的dp练手题. hdu 2844 Coins 多重背包 就是一个10w的多重背包,每个物品的cost同时也作为value去做背包,我们求的是每个容量下的价值,所以没

hdu 1011 Starship Troopers (依赖背包 树形dp)

题目: 链接:点击打开链接 题意: n个房间组成一棵树,你有m个战队,从1号房间开始依次clear每个房间,在每个房间需要花费的战队个数是bugs/20,得到的价值是the possibility of capturing a brain,求最大的价值. 算法: 树形dp,有依赖的背包问题.(依次clear每个房间) 思路: 状态转移dp[i][j]表示根结点为i时(房间i)花费j个战队能够得到的最大价值(捕捉到一个brain最大的可能值).递归求出每个根结点处的最大值,最后dp[1][m]就是