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的更多相关文章

  1. [HAOI2018]奇怪的背包 (DP,数论)

    [HAOI2018]奇怪的背包 \(solution:\) 首先,这一道题目的描述很像完全背包,但它所说的背包总重量是在模P意义下的,所以肯定会用到数论.我们先分析一下,每一个物品可以放无数次,可以达 ...

  2. 题解-HAOI2018全套

    去冬令营转了一圈发现自己比别人差根源在于刷题少,见过的套路少(>ω<) 于是闲来无事把历年省选题做了一些 链接放的都是洛谷的,bz偷懒放的也是链接 AM.T1 奇怪的背包 Problem ...

  3. Solution -「洛谷 P4389」付公主的背包

    \(\mathcal{Description}\)   Link.   容量为 \(n\),\(m\) 种物品的无限背包,求凑出每种容量的方案数,对 \(998244353\) 取模.   \(n,m ...

  4. POJ1112 Team Them Up![二分图染色 补图 01背包]

    Team Them Up! Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7608   Accepted: 2041   S ...

  5. HDU 3033 分组背包变形(每种至少一个)

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. POJ1837 Balance[分组背包]

    Balance Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13717   Accepted: 8616 Descript ...

  7. vijos1431[noip2007]守望者的逃离(背包动规)

    描述 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者 在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这 个荒岛施咒,这座岛很快就会 ...

  8. 【BZOJ-2427】软件安装 Tarjan + 树形01背包

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 960  Solved: 380[Submit][Status ...

  9. 【BZOJ-1042】硬币购物 容斥原理 + 完全背包

    1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1811  Solved: 1057[Submit][Stat ...

  10. ZOJ 3812 We Need Medicine(dp、背包、状态压缩、路径记录)

    参考:http://blog.csdn.net/qian99/article/details/39138329 参考的链接里说明得很好,注释也很好...thanks for sharing 朴素的想法 ...

随机推荐

  1. Linux Centos7 环境基于Docker部署Zookeeper服务搭建实战

    配置Zookeeper安装目录 在宿主机配置zookeeper安装目录:/docker/develop/zookeeper 并且在文件夹创建 data 和logs 目录: mkdir -p /dock ...

  2. 006一句话解决主机pc,Vmware虚拟机,开发板之间的ping问题

  3. vc++栈的简单实现

    栈的数据类型是先进后出 #ifndef __MYSTACK__ #define __MYSTACK__ #include <Windows.h> typedef struct Node { ...

  4. $Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$

    $Luogu$ $Sol$ 首先当然是构建一棵最大生成树,然后对于一辆货车的起点和终点倍增跑$lca$更新答案就好.记得预处理倍增的时候不仅要处理走了$2^i$步后是那个点,还有这中间经过的路径权值的 ...

  5. $BZOJ1799\ Luogu4127$ 月之谜 数位统计$DP$

    AcWing Description Sol 看了很久也没有完全理解直接$DP$的做法,然后发现了记搜的做法,觉得好棒! 这里是超棒的数位$DP$的记搜做法总结   看完仿佛就觉得自己入门了,但是就像 ...

  6. java做插入时ID为自增获取到ID

    <selectKey keyProperty="id" resultType="int" order="AFTER"> sele ...

  7. spring之为什么要使用AOP(面向切片编程)?

    需求1-日志:在程序执行期间追踪正在发生的活动: 需求2-验证:希望计算器只处理正数的运算: 一.普通方法实现 Calculator.java package com.gong.spring.aop. ...

  8. Ceph 文件系统 CephFS 的实战配置,等你来学习 -- <4>

    Ceph 文件系统 CephFS 的介绍与配置 CephFs介绍 Ceph File System (CephFS) 是与 POSIX 标准兼容的文件系统, 能够提供对 Ceph 存储集群上的文件访问 ...

  9. nor flash之写保护

    背景 没有电池的嵌入式设备,很容易发生随机掉电.因此要让产品可靠稳定,就必须保证各种场景下的掉电安全. 例如系统更新过程随机掉电,不能导致系统无法启动.例如正常读写flash过程中掉电,最多正在传输的 ...

  10. asp.net core 3.x 通用主机是如何承载asp.net core的-上

    一.前言 上一篇<asp.net core 3.x 通用主机原理及使用>扯了下3.x中的通用主机,刚好有哥们写了篇<.NET Core 3.1和WorkerServices构建Win ...