1601:【例 5】Banknotes

时间限制: 1000 ms         内存限制: 524288 KB

【题目描述】

原题来自:POI 2005

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

【输入】

第一行一个数 n;

接下来一行 n 个整数 b1,b2,⋯,bn;

第三行 n 个整数 c1,c2,⋯,cn ,表示每种硬币的个数;

最后一行一个数 k,表示要凑的面值数。

【输出】

第一行一个数表示最少需要付的硬币数。

【输入样例】

3
2 3 5
2 2 1
10

【输出样例】

3

【提示】

数据范围与提示:

对于全部数据,1≤n≤200,1≤b1<b2<⋯<bn≤2×104,1≤ci,k≤2×104 。

sol:比较裸的完全背包??可以有两种优化:

二进制优化太水不说了

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=;
bool f=;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-');
ch=getchar();
}
while(isdigit(ch))
{
s=(s<<)+(s<<)+(ch^);
ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<)
{
putchar('-');
x=-x;
}
if(x<)
{
putchar(x+'');
return;
}
write(x/);
putchar((x%)+'');
return;
}
inline void writeln(ll x)
{
write(x);
putchar('\n');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) writeln(x)
const int N=,M=;
int n,m,B[N],C[N],dp[M];
int main()
{
int i,j,k;
R(n);
for(i=;i<=n;i++) R(B[i]);
for(i=;i<=n;i++) R(C[i]);
R(m);
memset(dp,,sizeof dp);
dp[]=;
for(i=;i<=n;i++)
{
for(j=;j<=C[i]&&j*B[i]<=m;j<<=)
{
for(k=m;k>=j*B[i];k--) dp[k]=min(dp[k],dp[k-j*B[i]]+j);
}
}
Wl(dp[m]);
return ;
}
/*
input
3
2 3 5
2 2 1
10
output
3 input
10
6 17 111 249 250 495 496 497 498 499
100 100 100 100 1 100 100 100 100 100
500
output
6 input
3
300 700 4800
10000 10000 10000
5000
output
10
*/

二进制优化

单调队列优化:对于模Bi相同的几个权值之间的dp转移,可以用单调队列优化,令权值V=j+k*Bi,dp[V]=min(dp[V],dp[j+k'*Bi]+k-k‘),所以可以用dp[j+k*Bi]-k最小为队首的单调队列来优化成n*m,(细节:为了防止被反复统计,应该先插入当前节点再更新当前节点的dp值)

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=;
bool f=;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-');
ch=getchar();
}
while(isdigit(ch))
{
s=(s<<)+(s<<)+(ch^);
ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<)
{
putchar('-');
x=-x;
}
if(x<)
{
putchar(x+'');
return;
}
write(x/);
putchar((x%)+'');
return;
}
inline void writeln(ll x)
{
write(x);
putchar('\n');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) writeln(x)
const int N=,M=;
int n,m,B[N],C[N],dp[M];
struct Data
{
int Shuz,Weiz;
}Ddq[M];
int main()
{
int i,j,k;
R(n);
for(i=;i<=n;i++) R(B[i]);
for(i=;i<=n;i++) R(C[i]);
R(m);
memset(dp,,sizeof dp);
dp[]=;
for(i=;i<=n;i++)
{
for(j=;j<B[i];j++)
{
int Head=,Tail=;
for(k=;;k++)
{
int x=k*B[i]+j; if(x>m) break;
while(Head<Tail&&Ddq[Head].Weiz<k-C[i]) Head++;
while(Head<=Tail&&dp[x]-k<Ddq[Head].Shuz-Ddq[Head].Weiz) Tail--;
Ddq[++Tail]=(Data){dp[x]-k,k};
dp[x]=min(dp[x],Ddq[Head].Shuz+k);
}
}
}
Wl(dp[m]);
return ;
}
/*
input
3
2 3 5
2 2 1
10
output
3
*/

单调队列优化

一本通1601【例 5】Banknotes的更多相关文章

  1. 【一本通1329:【例8.2】细胞&&洛谷P1451 求细胞数量】

    1329:[例8.2]细胞 [题目描述] 一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数.如: 阵列 4 10 023 ...

  2. 「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和异或(Trie

    题目描述 原题来自:CODECHEF September Challenge 2015 REBXOR 1​​≤r​1​​<l​2​​≤r​2​​≤N,x⨁yx\bigoplus yx⨁y 表示 ...

  3. LOJ#10064. 「一本通 3.1 例 1」黑暗城堡

    LOJ#10064. 「一本通 3.1 例 1」黑暗城堡 题目描述 你知道黑暗城堡有$N$个房间,$M$条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设$D_i$为如果 ...

  4. 「LOJ#10050」「一本通 2.3 例 2」The XOR Largest Pair (Trie

    题目描述 在给定的 $N$ 个整数 $A_1,A_2,A_3...A_n$ 中选出两个进行异或运算,得到的结果最大是多少? 输入格式 第一行一个整数$N$. 第二行$N$个整数$A_i$. 输出格式 ...

  5. 「LOJ#10072」「一本通 3.2 例 1」Sightseeing Trip(无向图最小环问题)(Floyd

    题目描述 原题来自:CEOI 1999 给定一张无向图,求图中一个至少包含 333 个点的环,环上的节点不重复,并且环上的边的长度之和最小.该问题称为无向图的最小环问题.在本题中,你需要输出最小环的方 ...

  6. 「LOJ#10034」「一本通 2.1 例 2」图书管理 (map

    题目描述 图书管理是一件十分繁杂的工作,在一个图书馆中每天都会有许多新书加入.为了更方便的管理图书(以便于帮助想要借书的客人快速查找他们是否有他们所需要的书),我们需要设计一个图书查找系统. 该系统需 ...

  7. 「LOJ#10043」「一本通 2.2 例 1」剪花布条 (KMP

    题目描述 原题来自:HDU 2087 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? 输入格式 输入数据 ...

  8. 一本通 1615:【例 1】序列的第 k 个数

    传送门 我在这里! 思路 输入一个序列的前三个数并求出这个序列的第K项,这个数列不是等比序列就是等差数列,等差数列比较好判断,如果序列中\(a_{i+2}-a_{i+1}=a_{i+1}-a_{i}\ ...

  9. LOJ #10131 「一本通 4.4 例 2」暗的连锁

    LOJ #10131 「一本通 4.4 例 2」暗的连锁 给一棵 \(n\) 个点的树加上 \(m\) 条非树边 , 现在需要断开一条树边和一条非树边使得图不连通 , 求方案数 . $n \le 10 ...

随机推荐

  1. <<linux device driver,third edition>> Chapter 3:Char Drivers

    The Internal Representation of Device Numbers Within the kernel,the dev_t type(defined in linux/type ...

  2. Android学习之基础知识九 — 数据存储(持久化技术)之使用LitePal操作数据库

    上一节学习了使用SQLiteDatabase来操作SQLite数据库的方法,接下来我们开始接触第一个开源库:LitePal.LitePal是一款开源的Android数据库框架,它采用了对象关系映射(O ...

  3. Linux命令——df/du/time

    一.df(disk free) df命令可以用来检查 linux服务器的文件系统的磁盘空间占用情况,可以知道硬盘被占用了多少空间,目前还剩下多少空间等信息. 1)命令格式 df [参数] 文件名 2) ...

  4. C语言学习快速笔记

    想看java底层的代码,调用了native方法,所以简单的学习了下C,看的是C程序设计语言这本书,主要是在学习基本语法,关于操作系统指令这块都没看. #define关键字用来定义常量,(定义和声明不一 ...

  5. Apache cxf暴露接口以及客户端调用之WebService初步理解

    在我们真实的项目中,经常会调用别人提供给我们的接口,或者在自己的团队中, restful风格的前后端分离也经常会提供一个后端接口暴露出去供app,或者.net/C/C++程序员去调用,此时就需要使用到 ...

  6. java算法----排序----(7)堆排序

    package log; import java.util.Arrays; public class Test4 { /** * 堆排序 * * @param args */ public stati ...

  7. Kafka:Configured broker.id 2 doesn't match stored broker.id 0 in meta.properties.

    在安装Kafka集群的时候,碰到这个问题. 我们知道在搭建Kafka集群的时候,我们需要设置broker.id,以作为当前服务器在整个集群的唯一标志. 网上搜查资料是说,log.dirs目录下的met ...

  8. Linux系统安装IDS(snort工具)

    第一步:预装daq所需程序 snort使用数据采集器(daq)监听防火墙数据包队列,所以按照daq.需预装的程序有:flex.bison.libcap. sudo apt-get install fl ...

  9. Python从菜鸟到高手(5):数字

    1 基础知识   Python语言与其他编程语言一样,也支持四则运算(加.减.乘.除),以及圆括号运算符.在Python语言中,数字分为整数和浮点数.整数就是无小数部分的数,浮点数就是有小数部分的数. ...

  10. Mvc_前后端绑定数据json集合

    ViewBag.SysModuleList =new  List<SysModule>(){.....}; var data = @Html.Raw(Json.Encode(ViewBag ...