【板+背包】多重背包 HDU Coins

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

【题意】

  • 给定n种价值为Ci,个数为Wi的硬币,问在1~V中的这些数中哪些数能由这些硬币组成?

【思路】

  • 多重背包,二进制优化,时间复杂度为O(V*log∑ni)

【Accepted】

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<string>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9
10 using namespace std;
11 typedef long long ll;
12 const int maxn=1e5+2;
13
14 int n,v;
15 int c[maxn],w[maxn];
16 int dp[maxn];
17 void ZOP(int cost,int wei)
18 {
19     for(int i=v;i>=cost;i--)
20     {
21         dp[i]=max(dp[i],dp[i-cost]+wei);
22     }
23 }
24
25 void CPP(int cost,int wei)
26 {
27     for(int i=cost;i<=v;i++)
28     {
29         dp[i]=max(dp[i],dp[i-cost]+wei);
30     }
31 }
32
33 void MTP(int cost,int wei,int cnt)
34 {
35     if(v<=cnt*cost)
36     {
37         CPP(cost,wei);
38         return;
39     }
40     int k=1;
41     while(k<=cnt)
42     {
43         ZOP(k*cost,k*wei);
44         cnt-=k;
45         k*=2;
46     }
47     ZOP(cnt*cost,cnt*wei);
48 }
49 int main()
50 {
51     while(~scanf("%d%d",&n,&v))
52     {
53         if(n==0&&v==0) break;
54         for(int i=0;i<n;i++)
55         {
56             scanf("%d",&c[i]);
57         }
58         for(int i=0;i<n;i++)
59         {
60             scanf("%d",&w[i]);
61         }
62         memset(dp,0,sizeof(dp));
63         for(int i=0;i<n;i++)
64         {
65             MTP(c[i],c[i],w[i]);
66         }
67         int cnt=0;
68         for(int i=1;i<=v;i++)
69         {
70             if(dp[i]==i)
71             {
72                 cnt++;
73             }
74         }
75         printf("%d\n",cnt);
76     }
77     return 0;
78 }

背包模板

时间: 2024-12-30 02:45:18

【板+背包】多重背包 HDU Coins的相关文章

HDU2191_悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(背包/多重背包)

解题报告 题目传送门 题意: 中文不多说; 思路: 基础多重背包,每个物品有多个可以选,转换成01背包解. #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int main() { int t,i,j,n,m,v,p,h,cc,w[1010],c[1010],dp[1010]; scanf("%d",&

hdoj1171 Big Event in HDU(01背包 || 多重背包)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1171 题意 老师有一个属性:价值(value).在学院里的老师共有n种价值,每一种价值value对应着m个老师,说明这m个老师的价值都为value.现在要将这些老师从人数上平分成两个院系,并且希望平分后两个院系老师的总价值A和B应尽可能地相等,求A和B的值(A>=B). 思路 由于每种老师的个数是有限的,所以使用多重背包解决.由于测试数据不是很严格,所以使用01背包也可以通过. 代码 01背包: 1

洛谷P2851 [USACO06DEC]最少的硬币The Fewest Coins(完全背包+多重背包)

题目描述 Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of coins he

POJ 3260 The Fewest Coins 最少硬币个数(完全背包+多重背包,混合型)

题意:FJ身上有各种硬币,但是要买m元的东西,想用最少的硬币个数去买,且找回的硬币数量也是最少(老板会按照最少的量自动找钱),即掏出的硬币和收到的硬币个数最少. 思路:老板会自动找钱,且按最少的找,硬币数量也不限,那么可以用完全背包得出组成每个数目的硬币最少数量.而FJ带的钱是有限的,那么必须用多重背包,因为掏出的钱必须大于m,那么我们所要的是大于等于m钱的硬币个数,但是FJ带的钱可能很多,超过m的很多倍都可能,那么肯定要有个背包容量上限,网上说的根据抽屉原理是m+max*max,这里的max指

【动态规划】背包问题(一) 01背包 完全背包 多重背包

一.01背包 有N件物品和一个容量为V的背包.第i件物品的价格(即体积,下同)是w[i],价值是c[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 这是最基础的背包问题,总的来说就是:选还是不选,这是个问题<( ̄ˇ ̄)/ 相当于用f[i][j]表示前i个背包装入容量为v的背包中所可以获得的最大价值. 对于一个物品,只有两种情况 情况一: 第i件不放进去,这时所得价值为:f[i-1][v] 情况二: 第i件放进去,这时所得价值为:f[i-1][v-c[i]]+w

CRB and His Birthday 01背包 + 多重背包

CRB and His Birthday 题目抽象:背包问题,这里x个物品的价值是a * x + b (x > 0)  or 0 (x = 0). 分析:将物品按购买数量分类  1. 1件,  2 多件(>1).  对于一件的情况是01背包.  对于多件的情况是多重背包. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int dp

动态规划之背包问题-01背包+完全背包+多重背包

01背包 有n种不同的物品,每种物品分别有各自的体积 v[i],价值 w[i]  现给一个容量为V的背包,问这个背包最多可装下多少价值的物品. 1 for(int i = 1; i <= n; i++) 2 for(int j = V; j >= v[i]; j--) 3 dp[j] = max(dp[j], dp[j-v[i]]+w[i]); //dp[V]为所求 完全背包 01背包每种物品只能取一个, 完全背包即物品不记件数,可取多件. 1 for(int i = 1; i <= n

POJ 3260 完全背包+多重背包+思维

传送门:https://vjudge.net/problem/20465/origin 题意:你有n种钞票,面值为c[i],数量为v[i],便利店老板有无数张面值为c[i]的钞票,问你买一个价值为T的物品,最少需要经手多少张钞票,老板找零的钞票数也算经手的钞票数 题解:因为我的钞票是有限的,所以将自己看作一个多重背包,老板的钞票是无限的,所以将老板的钞票看做一个完全背包,定义状态dp[i]最少花费多少张钞票可以买价值为i的物品 边界:dp[0]=0; 目的:ans=min(dp1[i]+dp2[

背包之01背包、完全背包、多重背包详解

首先说下动态规划,动态规划这东西就和递归一样,只能找局部关系,若想全部列出来,是很难的,比如汉诺塔.你可以说先把除最后一层的其他所有层都移动到2,再把最后一层移动到3,最后再把其余的从2移动到3,这是一个直观的关系,但是想列举出来是很难的,也许当层数n=3时还可以模拟下,再大一些就不可能了,所以,诸如递归,动态规划之类的,不能细想,只能找局部关系. 1.汉诺塔图片 (引至杭电课件:DP最关键的就是状态,在DP时用到的数组时,也就是存储的每个状态的最优值,也就是记忆化搜索) 要了解背包,首先得清楚

poj1014 dp 多重背包

1 //Accepted 624 KB 16 ms 2 //dp 背包 多重背包 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 using namespace std; 7 const int imax_n = 120005; 8 int f[imax_n]; 9 int amount[7]; 10 int v; 11 int n=6; 12 int max(int a,int b) 1