<背包>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 朴素的想法 ...
随机推荐
- 小小知识点(二十二)显示屏与主机之间连接,出现无信号字样时,应检查是否正确选择集显和独显VGA接口
显示屏与主机之间连接,出现无信号字样时,应检查是否正确选择集显和独显VGA接口 通过VGA接口判断集成显卡和独立显卡.在台式机主机上,VGA接口竖着放置的说明是集成显卡,VGA接口横着放置的说明是独立 ...
- SpringBoot 总结篇
时至今日,SpringBoot 系列文章也算是告一段落,回想起当初立flag的情景,仿佛还历历在目.用一个月时间学完 SpringBoot 并整理成文章?又定一些异想天开计划,当时这样 ...
- Java工作流引擎节点接收人设置“按自定义SQL计算”系列讲解
关键字: 驰骋工作流程快速开发平台 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎. 开发者表单 拖拽式表单 工作流系统CCBPM节点访问规则接收人规则 适配数据库: o ...
- SQL server 基本语句
--查询数据库是否存在 if exists ( select * from sysdatabases where [name]='TestDB') print 'Yes, the DB exists' ...
- 你不得不了解Helm 3中的5个关键新特性
Helm是Kubernetes的一个软件包管理器.两个月前,它发布了第三个主要版本,Helm 3.在这一新版本中,有许多重大变化.本文将介绍我认为最关键的5个方面. 1. 移除了Tiller Helm ...
- Numpy常用方法及应用总汇
目录 Numpy 1.基本操作 1.1数组转换 1.2数组生成 1.3文件读取 1.4查看操作 2.数据类型 2.1指定数据类型: 2.2查看数据类型 2.3数据类型转换 3.数组运算 3.1数组间运 ...
- 从源码角度来看BeanFactory和ApplicationContext的关系
大家好,我是小黑,这是年前的最后一篇推文,提前祝大家新年快乐~~ 这次我们从源码角度来聊聊BeanFactory和ApplicationContext的关系,讲一些网上文章不曾提到的点. 官方描述 先 ...
- Django2.2 中间件的使用
中间件:AOP中间件,在Django中内置了一些项目自带的中间件,那么中间件是什么呢 这里说明一下,一开始我也不太清楚中间件到底有什么用(大家也别急,下面会有详细的例子给大家解释)--------&g ...
- 区间dp - 送外卖
When we are focusing on solving problems, we usually prefer to stay in front of computers rather tha ...
- Lambda表达式(lambda expression)⭐⭐⭐⭐⭐
原作者 lambda表达式(lambda expression)实际上是匿名函数一种表示形式, 即没有函数名的函数:参数列表=>表达式或语句块,在我看来主要目是为了简化代码编写,提高代码可读性而 ...