<背包>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 朴素的想法 ...
随机推荐
- appium启动app(android)
android Appium 启动APP至少需要5个参数 'platformVersion','deviceName'.'appPackage'.'appActivity'.'platform ...
- $Poj1037\ A\ Decorative\ Fence$ 计数类$DP$
Poj AcWing Description Sol 这题很数位$DP$啊, 预处理$+$试填法 $F[i][j][k]$表示用$i$块长度不同的木板,当前木板(第$i$块)在这$i$块木板中从小到 ...
- java如何实现在线支付讲解
转载:https://www.cnblogs.com/haorun/p/6728466.html 国内电子商务系统实现的基本流程如下: 客户在系统内下订单 -> 系统根据订单生成支付宝接口url ...
- Oracle 数据泵expdq,impdq
使用数据泵技术实现逻辑备份 数据泵概述 数据泵(DATA PUMP)是一种在数据库之间.数据库与操作系统之间,高速传输数据的技术(10g推出). 逻辑备份概述 逻辑备份是对数据库对象(如用户.表.存储 ...
- 【转】21个免费的UI界面设计工具、资源及网站
本文将介绍21个免费的UI界面设计工具.资源及网站,如果你在做用户体验设计.界面设计.产品设计.JS前段开发.手机产品设计以及iPad和平板电脑产品设计,不妨来看看. AD: 2013云计算架构师峰会 ...
- Promise里的代码为什么比setTimeout先执行
当浏览器或者Node拿到一段代码时首先做的就是传递给JavaScript引擎,并且要求它去执行. 然而,执行 JavaScript 并非一锤子买卖,宿主环境当遇到一些事件时,会继续把一段代码传递给 J ...
- linux下解压缩文件中文乱码问题的解决
在windows上压缩的文件,是以系统默认编码中文来压缩文件.由于zip文件中没有声明其编码,所以linux上的unzip一般以默认编码解压,中文文件名会出现乱码. 虽然2005年就有人把这报告为bu ...
- Scala实践11
1.1泛型类 泛型类是将类型作为参数的类.它们对集合类特别有用. 定义泛类型:泛型类将类型作为方括号内的参数[].一种惯例是使用字母A作为类型参数标识符,但是可以使用任何参数名称. class Sta ...
- 【C_Language】---C语言const用法总结
C语言关键字const相信对于不少C语言新手是既陌生又熟悉的,好像经常见,但是却不知道为何用,怎么用?学习至此,总结一下const的用法,使用程序来帮助你理解该关键字,希望能帮到像我一样的新手. 我看 ...
- spark和mapreduce的区别
spark和mapreduced 的区别map的时候处理的时候要落地磁盘 每一步都会落地磁盘 reduced端去拉去的话 基于磁盘的迭代spark是直接再内存中进行处理 dag 执行引擎是一个job的 ...