<背包>solution-POJ1742_Coins
People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some coins.He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.
You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.
Input
The input contains several test cases. The first line of each test case contains two integers n(1<=n<=100),m(m<=100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1<=Ai<=100000,1<=Ci<=1000). The last test case is followed by two zeros.
Output
For each test case output the answer on a single line.
Sample Input
3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0
Sample Output
8
4
先给人话:给你n种硬币,面值为ai,每种有bi个,问你能凑成1~m中多少种面值,
这题你看多重背包,直接二进制分组就好了,但是我太蔡了所以当时没想到 ,等一下再讲,
先说说我的做法:
首先,\(f[i][j]\)走起
\(f[i][j]\)表示前i种硬币凑成j元时第i种硬币剩余的个数,然后列出方程
首先用\(f[i][j]=-1\)表示前i种硬币无论如何都不能凑出j元
\(f[i][j] = B[i]\) \((f[i-1][j]!=-1)\) ,解释:在前i-1种硬币能凑出j元的时候,那还要第i种硬币干嘛?直接赋值成第i种硬币的数量
\(f[i][j] = f[i-1][j-A[i]]-1\) \((j>=A[i])\),解释:
转移之前的状态时前i-1个硬币组成了j-A[i]元所花的第i-1个硬币的方案数,
转移时,花了第i种硬币1个以凑成j元,为什么要-1呢?因为不是花了1个硬币么///
其他情况,\(f[i][j] = -1\)
好,于是上代码(部分)
for(int i=1;i<=n;++i)
for(int j=0;j<=m;++j)
{
if(f[i-1][j]>=0)
f[i][j]=B[i];
else if(j<A[i]||(j>=A[i]&&f[i-1][j-A[i]]<=0))
f[i][j]=-1;
else if(j>=A[i])
f[i][j]=f[i-1][j-A[i]]-1;
}
这里的边界条件可能有点问题,各位大佬见谅啊(反正这不是正解)
好,Submit
Memory Limit Exceeded,标准结局
考虑优化,
咦,你看这个f又大又圆这个\(f[i][j]\)会从\(f[i-1][...]\)转移过来,还记得背包里面我们怎么把二维转成一维么,直接滚掉就可以了,于是,状态转移方程:
$f[j] = B[i] $ \((f[j] != -1)\)
\(f[j]=f[j-A[i]]-1\) \((j>=A[i])\)
其他情况,\(f[j] = -1\)
注意,\(f[0]=0\)
然后计算一下时间复杂度,
\(O(nm)\),最坏的时候1.5亿,
再看看源题库,poj,笑容逐渐消失
但是时限给了3秒啊!刚好能卡过去!!!
好,上Code:
#include <cstdio>
#include <cctype>
#include <iostream>
#include <cstring>
#include <queue>
#define reg register
using namespace std;
const int MaxN=101;
const int MaxM=100001;
template <class t> inline void rd(t &s)
{
s=0;
reg char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
return;
}
int f[MaxM];
int w[MaxN],st[MaxN];
int n,m;
inline void work()
{
reg int ans=0;
memset(f,-1,sizeof f);f[0]=0;
for(int i=1;i<=n;++i)
rd(w[i]);
for(int i=1;i<=n;++i)
rd(st[i]);
for(int i=1;i<=n;++i)
for(int j=0;j<=m;++j)
{
if(f[j]>=0)
f[j]=st[i];
else if(j>=w[i])
f[j]=f[j-w[i]]-1;
}
for(int i=1;i<=m;++i)
if(f[i]>=0)
++ans;
printf("%d\n",ans);
return;
}
signed main(void)
{
while(cin>>n>>m&&n&&m)
work();
return 0;
}
结束了?
结束了。还没完呢
这里提一下二进制分组的做法,
首先,我们要知道二进制分组是什么,
假设有物品的数量为9,分成9组数量为1的物品这样复杂度肯定不优秀,怎么办呢?二进制分组
把数量按照二进制分组:1、2、4,最后还剩下一个2,
这样分组既可以想分成9组一样组合枚举出所有的情况,又使复杂度降成了log,这十分的香
“可我没听懂你在说什么”
假设这9个物品每个物品体积为3,价值为4,那么经过二进制分组后的物品体积和价值应为:
体积: 3, 6,12, 6
价值: 4, 8,16, 8
“那怎么实现呢”
for(int i=1;i<=n;++i)
{
register int k=1;
read(N);read(w);read(c);
while(k<=N)
{
++n;
W[n]=w*k;
C[n]=c*k;
k<<=1;
}
if(N)
{
++n;
W[n]=w*N;
C[n]=c*N;
}
}
大概就是这个样子
具体的代码各位大佬自己上网搜
因为我实在是太蔡了awa
<背包>solution-POJ1742_Coins的更多相关文章
- [HAOI2018]奇怪的背包 (DP,数论)
[HAOI2018]奇怪的背包 \(solution:\) 首先,这一道题目的描述很像完全背包,但它所说的背包总重量是在模P意义下的,所以肯定会用到数论.我们先分析一下,每一个物品可以放无数次,可以达 ...
- 题解-HAOI2018全套
去冬令营转了一圈发现自己比别人差根源在于刷题少,见过的套路少(>ω<) 于是闲来无事把历年省选题做了一些 链接放的都是洛谷的,bz偷懒放的也是链接 AM.T1 奇怪的背包 Problem ...
- Solution -「洛谷 P4389」付公主的背包
\(\mathcal{Description}\) Link. 容量为 \(n\),\(m\) 种物品的无限背包,求凑出每种容量的方案数,对 \(998244353\) 取模. \(n,m ...
- POJ1112 Team Them Up![二分图染色 补图 01背包]
Team Them Up! Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7608 Accepted: 2041 S ...
- HDU 3033 分组背包变形(每种至少一个)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- POJ1837 Balance[分组背包]
Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 13717 Accepted: 8616 Descript ...
- vijos1431[noip2007]守望者的逃离(背包动规)
描述 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者 在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这 个荒岛施咒,这座岛很快就会 ...
- 【BZOJ-2427】软件安装 Tarjan + 树形01背包
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 960 Solved: 380[Submit][Status ...
- 【BZOJ-1042】硬币购物 容斥原理 + 完全背包
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1811 Solved: 1057[Submit][Stat ...
- ZOJ 3812 We Need Medicine(dp、背包、状态压缩、路径记录)
参考:http://blog.csdn.net/qian99/article/details/39138329 参考的链接里说明得很好,注释也很好...thanks for sharing 朴素的想法 ...
随机推荐
- Spring Boot 整合 slf4j+log4j 实现日志管理
一:首先新建一个jar项目,如下图: 二:添加log4j的依赖,如下pom.xml文件: <project xmlns="http://maven.apache.org/POM/4.0 ...
- $Poj2228$/洛谷$SP283\ Naptime$ 环形$DP$
Luogu 一定要记得初始化为-inf!!! Description 在某个星球上,一天由N小时构成.我们称0-1点为第一个小时,1-2点为第二个小时,以此类推.在第i个小时睡觉能恢复Ui点体力.在这 ...
- 二、webdriver API
目录 1. webdriver中常用属性 2. 浏览器页面操作 3. 鼠标操作 4. 键盘操作 5. 下拉框操作 1. webdriver中常用属性 import time from selenium ...
- 1060 爱丁顿数 (25 分)C语言
英国天文学家爱丁顿很喜欢骑车.据说他为了炫耀自己的骑车功力,还定义了一个"爱丁顿数" E ,即满足有 E 天骑车超过 E 英里的最大整数 E.据说爱丁顿自己的 E 等于87. 现给 ...
- K8S集群搭建
K8S集群搭建 摘要 是借鉴网上的几篇文章加上自己的理解整理得到的结果,去掉了一些文章中比较冗余的组件和操作,力争做到部署简单化. K8S组件说明 Kubernetes包含两种节点角色:master节 ...
- [Windows10]记一次修复注册表相关血案:该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置”页面中创建关联。
今天闲得蛋疼清理了一下右键菜单,于是在之后某时刻使用Everything的“双击路径列打开目录”功能时发现异常: [Window Title] Everything.exe [Content] 该文件 ...
- SpringBoot中SpringMVC的自动配置以及扩展
一.问题引入 我们在SSM中使用SpringMVC的时候,需要由我们自己写SpringMVC的配置文件,需要用到什么就要自己配什么,配置起来也特别的麻烦.我们使用SpringBoot的时候没有进行配置 ...
- 探究Dubbo的拓展机制: 下
承接上篇, 本篇博文的主题就是认认真真捋一捋, 看一下 Dubbo是如何实现他的IOC / AOP / 以及Dubbo SPI这个拓展点的 总览: 本篇的话总体上分成两部分进行展开 第一点就是 Dub ...
- 【移动测试】你的测试用例中,是否包含App前后台切换
App前后台切换是我们平时常用的一个操作,比如:按手机的home键将应用置于后台.直接按手机电源键关闭屏幕或者通过最近打开的应用列表切换应用等,由此,我们可以得出结论:当app置于前台时,它的页面对我 ...
- Scala实践2
一.Scala基本类型和操作 1.1 基本类型 Scala的基本类型与Java基本类型相同,都是byte.short.int.long.char.string.float.double.boolea ...