传送门

参考资料:

  [1]:https://www.cnblogs.com/jbelial/articles/2116074.html

  [2]:https://www.luogu.org/problemnew/solution/P1616

题意:

  有一个小猪存钱罐,里面有各式各样的硬币,每种硬币有不同的面值和重量。

  现测量出存钱罐初始的重量(E)和存满钱时的重量(F),问在这N种硬币中,如何选取,使得选取的硬币的总重量恰好等于(F-E),且总价值最小。

  如果可以找到,输出"The minimum amount of money in the piggy-bank is num".(num : 总和最小的面值)

  如果不能通过组合使得硬币总重量恰好等于(F-E),则输出"This is impossible."

分析:

  乍一看,和“01”背包很想,所不同的是,在“01”背包中,第 i 种物品只有两种选择,拿或者不拿;

  而此题,第 i 种面值的硬币可不止有拿与不拿这两种选择,而是有拿0,1,2,.....,k个,共(k+1)种选择,其中k满足 k*w[i] <= (F-E);

  这种每种物品都有无限件可用的问题,称为“完全背包”问题。

题解:

  1.完全背包转“01”背包

    思路:将一种物品拆成多件物品。

    考虑到第 i 种物品最多选 (F-E) / w[ i ] 件;

    于是可以把第 i 种物品转化为 (F-E) / w[ i ] 件费用及价值均不变的物品,然后求解这个01背包问题。

    如果开个二维的dp数组,指定不可行,具体为什么,请自行思考;

    提示:假设每种硬币都可拆成 k 个(k 最大可达 10000),N种硬币则可拆成 N*k 个(N最大为500),所以最坏的情况是可拆成 N*k = 5e6 个物品。

    比较好用的方法就是使用滚动数组优化空间。

    更高效的转化方法是:把第 i 种物品拆成重量为 w[i]×2k、价值为 p[i]×2k 的若干件物品,其中k满足 w[i]×2k < (F-E)。

    这是二进制的思想,因为不管最优策略选几件第 i 种物品,总可以表示成若干个 2k 件物品的和。

    这样把每种硬币拆成 log2( (F-E) / w[i]) ) 件物品,是一个很大的改进。

AC代码:

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const int maxn=+; int n;
int e,f;
int p[maxn],w[maxn];
int dp[]; void Solve()
{
int v=f-e;
for(int j=;j <= v;++j)
dp[j]=INF;
dp[]=; for(int i=;i <= n;++i)
{
for(int k=,cur=(<<k)*w[i];cur <= v;++k)///第i个物品选2^k个
{
for(int j=v;j >= cur;--j)
dp[j]=min(dp[j],dp[j-cur]+(<<k)*p[i]); cur <<= ;
}
}
if(dp[v] < INF)
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[v]);
else
printf("This is impossible.\n");
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&e,&f);
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d%d",p+i,w+i);
Solve();
}
return ;
}

  2.我们有更优的O(VN)的算法

    定义dp[ i ][ j ] : 前 i 件物品恰好组成重量 j 的最小面值;

    第 i 件物品的状态转移方程为:

 for(int j=w[i];j <= v;++j)
dp[j]=min(dp[j],dp[j-w[i]]+p[i]);

    完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第 i 种物品”这种策略时,

    却正需要一个可能已选入第 i 种物品的子结果 dp[ i ][ v-w[i] ],所以就可以并且必须采用 j = w[i]..v 的顺序循环。

    以上思路摘抄自[1]%%%%%%%%%%%%%%%

AC代码:

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const int maxn=+; int n;
int e,f;
int p[maxn],w[maxn];
int dp[]; void Solve()
{
int v=f-e;
for(int j=;j <= v;++j)
dp[j]=INF;
dp[]=; for(int i=;i <= n;++i)
for(int j=w[i];j <= v;++j)
dp[j]=min(dp[j],dp[j-w[i]]+p[i]); if(dp[v] < INF)
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[v]);
else
printf("This is impossible.\n");
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&e,&f);
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d%d",p+i,w+i);
Solve();
}
return ;
}

hdu 1114Piggy-Bank(完全背包)的更多相关文章

  1. hdu 2546 典型01背包

    分析:每种菜仅仅可以购买一次,但是低于5元不可消费,求剩余金额的最小值问题..其实也就是最接近5元(>=5)时, 购买还没有买过的蔡中最大值问题,当然还有一些临界情况 1.当余额充足时,可以随意 ...

  2. HDU 3127 WHUgirls(完全背包)

    HDU 3127 WHUgirls(完全背包) http://acm.hdu.edu.cn/showproblem.php? pid=3127 题意: 如今有一块X*Y的矩形布条, 然后有n种规格的x ...

  3. HDU 3535 分组混合背包

    http://acm.hdu.edu.cn/showproblem.php?pid=3535 题意:有n组工作,T时间,每个工作组中有m个工作,改组分类是s,s是0是组内至少要做一件,是1时最多做一件 ...

  4. HDU 4003 (树形DP+背包)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4003 题目大意:有K个机器人,走完树上的全部路径,每条路径有个消费.对于一个点,机器人可以出去再回来 ...

  5. HDU 1561 (树形DP+背包)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1561 题目大意:从树根开始取点.最多取m个点,问最大价值. 解题思路: cost=1的树形背包. 有 ...

  6. HDU 1011 (树形DP+背包)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1011 题目大意:树上取点,先取父亲,再取儿子.每个点,权为w,花费为cost,给定m消费总额,求最大 ...

  7. hdu 3535 AreYouBusy 分组背包

    AreYouBusy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  8. hdu 3339 In Action 背包+flyod

    In Action Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=333 ...

  9. hdu 1963 Investment 多重背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1963 //多重背包 #include <cstdio> #include <cstr ...

  10. hdu 2955 Robberies 0-1背包/概率初始化

    /*Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...

随机推荐

  1. [BUAA软工]第一次结对作业

    [BUAA软工]结对作业 本次作业所属课程: 2019BUAA软件工程 本次作业要求: 结对项目 我在本课程的目标: 熟悉结对合作,为团队合作打下基础 本次作业的帮助:理解一个c++ 项目的开发历程 ...

  2. [2019BUAA软件工程]第1次阅读作业

    [2019BUAA软件工程]第1次阅读作业 Tips Link 作业连接 [2019BUAA软件工程]第1次阅读作业 读<构建之法>的疑惑 个人开发流程(Personal Software ...

  3. Cocos2d-x项目创建方式

    刚接触cocos2d-x的时候,还只有2.x版本,尝试着将cocos2d-x项目创建功能加入到vs里面去,后来,引擎用Python封装好了好多个脚本文件,其中就包括create_project.py文 ...

  4. 美团外卖app可行性分析

    美团外卖app可行性分析 1 引言 1.1编写目的 年轻人追求时尚,快捷,因此外卖行业拥有广阔的消费群体:团购的兴起,也促进了人们的消费欲望,人们继续一个外卖平台,来满足他们的欲望.O2o模式的日渐完 ...

  5. 关于hash冲突的解决

    分离链接法:public class SeparateChainingHashTable<AnyType>{ private static final int DEFAULT_TABLE_ ...

  6. Maven项目中添加JDBC驱动

    在pom.xml配置文件中添加: <dependency> <groupId>mysql</groupId> <artifactId>mysql-con ...

  7. Socket、Session、Option和Pipe

    消息队列NetMQ 原理分析4-Socket.Session.Option和Pipe   消息队列NetMQ 原理分析4-Socket.Session.Option和Pipe 前言 介绍 目的 Soc ...

  8. The import * cannot be resolved

    背景 使用eclipse jee做练习的时候,下载了老师的项目源码.考虑到老师用的时myeclipse,目录结构略有不同,所有不想直接导入项目,又考虑到,可能环境不一样,会出现这样那样的问题,所以我的 ...

  9. 【Alpha发布】网站已经正式发布!

    Alpha版本发布说明 一.功能介绍 本团队所做的物理实验网站是以生成物理实验报告为基础功能的网站.Alpha版本具有的功能大体如下: Figure 1首页 1. 注册登录功能 用户可以通过在注册页通 ...

  10. Redis的五种数据类型

    官方的几篇很好的文章: https://redis.io/topics/data-types https://redis.io/topics/data-types-intro https://redi ...