hdu 1114Piggy-Bank(完全背包)
参考资料:
[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(完全背包)的更多相关文章
- hdu 2546 典型01背包
分析:每种菜仅仅可以购买一次,但是低于5元不可消费,求剩余金额的最小值问题..其实也就是最接近5元(>=5)时, 购买还没有买过的蔡中最大值问题,当然还有一些临界情况 1.当余额充足时,可以随意 ...
- HDU 3127 WHUgirls(完全背包)
HDU 3127 WHUgirls(完全背包) http://acm.hdu.edu.cn/showproblem.php? pid=3127 题意: 如今有一块X*Y的矩形布条, 然后有n种规格的x ...
- HDU 3535 分组混合背包
http://acm.hdu.edu.cn/showproblem.php?pid=3535 题意:有n组工作,T时间,每个工作组中有m个工作,改组分类是s,s是0是组内至少要做一件,是1时最多做一件 ...
- HDU 4003 (树形DP+背包)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4003 题目大意:有K个机器人,走完树上的全部路径,每条路径有个消费.对于一个点,机器人可以出去再回来 ...
- HDU 1561 (树形DP+背包)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1561 题目大意:从树根开始取点.最多取m个点,问最大价值. 解题思路: cost=1的树形背包. 有 ...
- HDU 1011 (树形DP+背包)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1011 题目大意:树上取点,先取父亲,再取儿子.每个点,权为w,花费为cost,给定m消费总额,求最大 ...
- hdu 3535 AreYouBusy 分组背包
AreYouBusy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Probl ...
- hdu 3339 In Action 背包+flyod
In Action Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=333 ...
- hdu 1963 Investment 多重背包
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1963 //多重背包 #include <cstdio> #include <cstr ...
- hdu 2955 Robberies 0-1背包/概率初始化
/*Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
随机推荐
- 洛谷P1004 方格取数-四维DP
题目描述 设有 N \times NN×N 的方格图 (N \le 9)(N≤9) ,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00 .如下图所示(见样例): A 0 0 0 0 0 ...
- HTTP请求头和响应头部包括的信息有哪些?
每个HTTP请求和响应都会带有相应的头部信息.默认情况下,在发送XHR请求的同时,还会发送下列头部信息: Accept:浏览器能够处理的内容类型 Accept-Charset:浏览器能够显示的字符集 ...
- BUAAMOOC项目终审报告
工作总结 我们是歪果仁带你灰开发团队.我们开发的项目是北航学堂(MOOC)的android客户端:BUAAMOOC. 目前我们完成了主要功能,包括UI设计,视频播放,视频下载,学习进度,个人信息等功能 ...
- C# wkhtmltopdf 将html转pdf(详解)
https://www.cnblogs.com/louby/p/905198.html转自,看文章只放了代码看起来云里雾里的,在此做些解析 使用说明: 1.首先呢,得安装下软件,地址下面有链接,文件里 ...
- 非post请求时整个url作为参数传递出现bug
在非post请求使用整个url作为参数传递到后台时会出现url被截断的bug,这时通过encodeURIComponent进行url的编码可以解决.示例如下: <!--参数url-->Ur ...
- 实验二 合作:王宏财 http://www.cnblogs.com/wanghongcai/
package 四则运算; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JOptionPane; ...
- [转帖]数据中心网络里的Underlay和Overlay
数据中心网络里的Underlay和Overlay https://blog.csdn.net/zjc801blog/article/details/54289683 2017年01月09日 15:47 ...
- SQLSERVER备份恢复后权限问题简单处理.
1. 同事的服务器出现无法访问表, 应用连不上数据库... 远程了下 发现. 使用业务用户登录数据库之后查询无法下拉帮助到表, 必须增加schemas才可以访问到具体的表. 2. 问题解决. 1. 修 ...
- Node fs模块同步读取写入追加
JS文件中const fs = require("fs");console.log("开始进入文件读取.."); //同步的写入var data = fs.re ...
- BZOJ1115[POI2009]石子游戏——阶梯Nim游戏
题目描述 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必 ...