题目描述:

  Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有n种面值的硬币,面值分别为b1, b2,…, bn. 但是每种硬币有数量限制,现在我们想要凑出面值k求最少要用多少个硬币.

  

  这一题其实很容易看出是一道背包问题,为什么我NOIP2018没有想到,此题应该属于多重背包问题,我们显然可以,将f[i]定为拼出i元需要的最少钞票数,将v定为花费的钞票数,将w定为这些钞票加起来的总价值,再利用多重背包的拆分方法。上链接已述,此处不多做叙述。

但重点在于怎样记录:一开始我的想法是将每个f[i]都记录其转移的来pre[i],输出的时候向下不断temp=pre[temp]来输出。但这样是不行的

错误代码如下:

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long ll;
inline int read()
{register int p(1),a(0);register char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();if(ch=='-') p=-1,ch=getchar();while(ch>='0'&&ch<='9') a=a*10+ch-48,ch=getchar();return a*p;
}
const int N=210,M=20010;
int n,m,f[M],b[N],biao[M][2],zh[M][N],pre[M],hole[N],c[N],temp=1;
int main()
{n=read();for(int i=1;i<=n;i++) b[i]=read();for(int i=1;i<=n;i++) c[i]=read();m=read();memset(f,0x3f,sizeof(f));f[0]=0;for(int i=1;i<=n;i++){temp=1;while((temp<<1)<=c[i]+1&&b[i]*temp<=m){for(int j=m;j>=b[i]*temp;j--) if(f[j]>f[j-b[i]*temp]+temp){f[j]=f[j-b[i]*temp]+temp;biao[j][0]=i,biao[j][1]=temp;pre[j]=j-b[i]*temp;}temp<<=1;}if((temp<<1)>=c[i]){temp=c[i]-temp+1;for(int j=m;j>=b[i]*temp;j--) if(f[j]>f[j-b[i]*temp]+temp){f[j]=f[j-b[i]*temp]+temp;biao[j][0]=i,biao[j][1]=temp;pre[j]=j-b[i]*temp;}}}printf("%d\n",f[m]);temp=m;while(temp){printf("%d ",temp);hole[biao[temp][0]]+=biao[temp][1];temp=pre[temp];}for(int i=1;i<=n;i++)printf("%d ",hole[i]); return 0;
}

这样做连样例都过不了,我们考虑是为什么。首先我们考虑01背包为什么要倒叙循环,因为这样就不会重复使用同一个物品。那么此算法的错误之处就出在这里。

样例中要求拼出的数是10,有2 3 5三个数,其中5 只有一个,那么我们从f[10] ( f[m] ) 开始循环,我们首先取到5,于是我们接着我们循环f[5]这时我们就发现biao[5]在第循环5的时候被修改过了,所以它也用的是5这张钞票,但5的钞票只有一张,于是就出现错误了,显然一维无法解决这个问题了,必须用二维。此题卡空间,int[3000][20000],消耗约228MB,而此题空间上限为64MB,而如果我们使用bool类型就可以过,我们用cun[i][j],表示在f[i][j]处是否发生转移而下一个要循环的其实是可以算出来为f[i-1][j-w[i]],就这样知道j为0为止

实现如下:

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long ll;
inline int read()
{register int p(1),a(0);register char ch=getchar();while((ch<'0'&&ch>'9')&&ch!='-') ch=getchar();if(ch=='-') p=-1,ch=getchar();while(ch>='0'&&ch<='9') a=a*10+ch-48,ch=getchar();return a*p;
}
const int N=210,M=20010,N2=3010;
int n,m,f[M],b[N],v[N2],w[N2],bef[N2],hole[N],c[N],temp=1,cnt=0,ji=0;
bool cun[N2][M];
int main()
{n=read();for(int i=1;i<=n;i++) b[i]=read();for(int i=1;i<=n;i++) c[i]=read();m=read();memset(f,0x3f,sizeof(f));f[0]=0;for(int i=1;i<=n;i++){temp=1;while((temp<<1)<=c[i]+1&&b[i]*temp<=m){v[++cnt]=temp;w[cnt]=b[i]*temp;bef[cnt]=i;temp<<=1;}if((temp<<1)>=c[i]){temp=c[i]-temp+1;v[++cnt]=temp;w[cnt]=b[i]*temp;bef[cnt]=i;temp<<=1;}}for(int i=1;i<=cnt;i++)for(int j=m;j>=w[i];j--){if(f[j]>f[j-w[i]]+v[i]){f[j]=f[j-w[i]]+v[i];cun[i][j]=true;}}printf("%d\n",f[m]);temp=m,ji=cnt;while(temp){while(!cun[ji][temp]&&ji) --ji;temp-=w[ji];hole[bef[ji]]+=v[ji];--ji;}for(int i=1;i<=n;i++)printf("%d ",hole[i]); return 0;
}

转载于:https://www.cnblogs.com/cold-cold/p/10015491.html

[POI2005]BAN-Bank Notes相关推荐

  1. DSY1531*Bank notes

    Description Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有n种面值的硬币,面值分别为b1, b2,..., bn. 但是每种硬币有数量限制,现在我 ...

  2. 提高篇 第五部分 动态规划 第5章 单调队列优化动态规划

    单调队列:是一种双端除列,其内部元素具有单调性. 最大队列 最小队列 操作: .插入:新元素插入队尾,删除除尾元素,直到找到插入后不会破坏单调性的为止. .获取最大(最小)值,访问队首元素. 单调队列 ...

  3. [SAP Dictionary]

    Words    Chinese (foreign) exchange gain 汇兑收益 (foreign) exchange loss 汇兑损失 (investment) support allo ...

  4. 【整理向】OJ上一些不(jiao)错(shui)的背包题

    CodeVS 1491 取物品 1047 邮票面值设计 3372 选学霸 1155 金明的预算方案 1014 装箱问题 BZOJ 3407: [Usaco2009 Oct]Bessie's Weigh ...

  5. 为什么数据库的内容像加密了_意外的负担(或者为什么我认为加密所有内容都不是个好主意)

    为什么数据库的内容像加密了 In psychology there is the term of affordances. It's the concept that an object afford ...

  6. MEMORY系列之“DDR概述”

    DDR全称为Double Data Rate Synchronous Dynamic Random Access Memory,从1996年三星公司提出到现在已经发展到了第六代. 1.DDR发展历程及 ...

  7. 【北邮国院大三上】电子商务法(e-commerce law)知识点整理——Banking Lawe-Payment

    北邮国院大三电商在读,随课程进行整理知识点.仅整理PPT和相关法条中相对重要的知识点,个人认为相对不重要的细小的知识点不列在其中.如有错误请指出.转载请注明出处,祝您学习愉快. Why are leg ...

  8. amazeui学习笔记--css(常用组件6)--图标Icon

    amazeui学习笔记--css(常用组件6)--图标Icon 一.总结 1.关注用法即可:在 HTML 上添加添加 am-icon-{图标名称} class. <span class=&quo ...

  9. SAP会计科目中英文对照表

    总帐科目 长文本 短文本 英文长文本 10010101 现金-CNY Cash on Hand - CNY Cash on Hand - CNY 10010102 现金-USD Cash on Han ...

  10. 1929年泡沫破裂: 又一次“剪羊毛”行动

    美联储从1929年到1933年紧缩货币流通量达1/3,注定会造成大衰退.                                                                 ...

最新文章

  1. pandas模块学习笔记2--基本功能
  2. java 鼠标拖动矩形_java – 用鼠标拖动创建矩形,而不是绘制
  3. windows docker redis 集群部署
  4. Halcon算子学习:smooth_object_model_3d
  5. python刷题相关资料汇总(一)
  6. MyBatis学习笔记(四) 注解
  7. HTML元素 - input type=hidden
  8. Android自定义控件学习(一)-----属性
  9. mysql pk_mysql_1
  10. 直接无序搜索 vs 先排序后搜索
  11. FastFDS集群配置说明
  12. 简单详细叙述FpGrowth算法思想(附python源码实现)
  13. 内地见证可以办理哪些香港银行卡?哪家更方便门槛要求更低?
  14. 【机器学习】数据增强(Data Augmentation)
  15. 编程专业人的良好习惯(练习、时间管理、压力、团队协作)
  16. 光流的基本概念和原理-Lucas–Kanade光流算法
  17. 威廉玛丽学院计算机专业,威廉玛丽学院CS排名2020年掌握的流程盘点
  18. 亲自面试汇丰银行面试题目总结
  19. 为什么淘宝京东使用不是每次都需要登录?
  20. Renix签名字段详解——网络测试仪实操

热门文章

  1. 实用技巧:使用 jQuery 异步加载 JavaScript 脚本
  2. Chrome 浏览器降级后浏览网站不保留用户数据问题原因及解决方法
  3. Python 技术篇-xlwt库不新建,直接读取已存在的excel并写入
  4. Manacher's algorithms(马拉车算法)最长回文子串
  5. 微信好友个性标签词云--微信数据分析(四)
  6. 非线性方程组求解Matlab实现 (多元牛顿方法、Broyden方法、Broyden方法2)
  7. 龙族幻想最新东京机器人位置_龙族幻想:东京·白月境活动介绍
  8. 项目总结二:人脸识别项目(Face Recognition for the Happy House)
  9. makefile笔记
  10. 基础笔记6(exception)