【数学】【背包】【NOIP2018】P5020 货币系统
Description
在网友的国度中共有 \(n\) 种不同面额的货币,第 \(i\) 种货币的面额为 \(a[i]\),你可以假设每一种货币都有无穷多张。为了方便,我们把货币种数为 \(n\)、面额数组为 \(a[1..n]\) 的货币系统记作 \((n,a)\)。
在一个完善的货币系统中,每一个非负整数的金额 \(x\) 都应该可以被表示出,即对每一个非负整数 \(x\),都存在 \(n\) 个非负整数 \(t[i]\) 满足 \(a[i] \times t[i]\) 的和为 \(x\)。然而, 在网友的国度中,货币系统可能是不完善的,即可能存在金额 \(x\) 不能被该货币系统表示出。例如在货币系统 \(n=3\), \(a=[2,5,9]\) 中,金额 \(1,3\) 就无法被表示出来。
两个货币系统 \((n,a)\) 和 \((m,b)\) 是等价的,当且仅当对于任意非负整数 \(x\),它要么均可以被两个货币系统表出,要么不能被其中任何一个表出。
现在网友们打算简化一下货币系统。他们希望找到一个货币系统 \((m,b)\),满足 \((m,b)\) 与原来的货币系统 \((n,a)\) 等价,且 \(m\) 尽可能的小。他们希望你来协助完成这个艰巨的任务:找到最小的 \(m\)。
Input
输入文件的第一行包含一个整数 \(T\),表示数据的组数。
接下来按照如下格式分别给出 \(T\) 组数据。 每组数据的第一行包含一个正整数 \(n\)。接下来一行包含 \(n\) 个由空格隔开的正整数 \(a[i]\)。
Output
输出文件共有 \(T\) 行,对于每组数据,输出一行一个正整数,表示所有与 \((n,a)\) 等价的货币系统 \((m,b)\) 中,最小的 \(m\)。
Solution
我居然被这个题差点搞退役……
观察题目给的样例,发现选择的货币集合是原集合的一个子集。
考虑证明,使用反证法,假设被选择的集合中,\(k\)是最小的在原集合中没有出现的数。因为新集合的元素能表示的原集合一定能表示,所以原集合一定存在一组数使得他们能表示出\(k\)。那么将那组数作为\(k\),在后面可以表示\(k\)能表示出的所有数字,同时会比选择\(k\)少选择一个数,选择更优。证毕。
于是这道题选择的一定是原集合的一个子集。
考虑按照证明的思路,本题可以进一步转化为选择最少的数字拼出集合中的所有数字。这个操作可以通过完全背包实现:按照集合元素大小将元素从小到大排序,使用bool背包求出所有能被表示的数。在扫到第\(i\)个数字时,如果第\(i\)个数字不能被表示出,则将其选进集合中,使用它更新答案,否则跳过。
时间复杂度\(O(Tn\max\{a\})\)
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rg register
#define ci const int
#define cl const long long
typedef long long int ll;
template <typename T>
inline void qr(T &x) {
rg char ch=getchar(),lst=' ';
while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst == '-') x=-x;
}
namespace IO {
char buf[120];
}
template <typename T>
inline void qw(T x,const char aft,const bool pt) {
if(x < 0) {x=-x,putchar('-');}
rg int top=0;
do {IO::buf[++top]=x%10+'0';} while(x/=10);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
}
const int maxn = 120;
const int maxt = 25010;
int t;
int n;
int MU[maxn];
bool frog[maxt];
void clear();
int main() {
qr(t);
while(t--) {
clear();
qr(n);
for(rg int i=1;i<=n;++i) qr(MU[i]);
int ans=0;
std::sort(MU+1,MU+1+n);
frog[0]=true;
for(rg int i=1;i<=n;++i) if(!frog[MU[i]]) {
++ans;
for(rg int j=0;j<=MU[n];++j) if(frog[j]) {
int k=j+MU[i];
if(k <= MU[n]) frog[k]=true;
else break;
}
}
qw(ans,'\n',true);
}
return 0;
}
void clear() {
n=0;
memset(MU,0,sizeof MU);
memset(frog,0,sizeof frog);
}
Summay
惨象,已使我目不忍视了。爆零,尤使我耳不忍闻。我还有什么话可说呢?沉默呵,沉默呵,不在沉默中爆发,就在沉默中灭亡。
【数学】【背包】【NOIP2018】P5020 货币系统的更多相关文章
- 背包 || NOIP 2018 D1 T2 || Luogu P5020 货币系统
题面:P5020 货币系统 题解: 显然要求的货币系统是当前货币系统的子集时答案会更优,于是考虑从当前货币系统中删数 一个大数如果能被其他小数表示出来,它就可以去掉 把数据排个序去个重,然后直接背包 ...
- Luogu P5020 货币系统
Luogu P5020 货币系统 先把$a$数组排一下序. 从最小的数开始选,显然最小这个数必须选,然后利用完全背包的思想,从$a_i$到最大值筛选一遍,将可以组成的打上标记. 在判断后面的数字时,如 ...
- P5020 货币系统
P5020 货币系统 题解 仔细分析... 这道题其实就是求所给数组中有多少个数字不能被该数组中的数字自由组合表示出来 比如样例1 3,10 不能被该集合里的数字表示出来,所以他们组成目标集合 6=3 ...
- 洛谷 P5020 货币系统
题目描述 在网友的国度中共有$ n $种不同面额的货币,第 i种货币的面额为 \(a[i]\),你可以假设每一种货币都有无穷多张.为了方便,我们把货币种数为\(n\).面额数组为 \(a[1..n]\ ...
- [NOIp2018] luogu P5020 货币系统
还在补暑假作业. 题目描述 你有一个由 NNN 种面值的货币组成的货币系统.定义两个货币系统等价,当且仅当 ∀x∈N∗\forall x\in\N^*∀x∈N∗ 要么同时能被两个货币系统表示,要么同时 ...
- @NOIP2018 - D1T2@ 货币系统
目录 @题目描述@ @题解@ @代码@ @题目描述@ 在网友的国度中共有 n 种不同面额的货币,第 i 种货币的面额为 a[i],你可以假设每一种货币都有无穷多张.为了方便,我们把货币种数为 n.面额 ...
- P5020 货币系统 题解
原题链接 简要题意: 求一个长度最小的货币系统与给出的货币系统等价.求这个货币系统的长度.等价的定义详见题目,不再赘述. 本文可能用到一些集合论,请放心食用. 算法一 \(n=2\) 时,只需判断两个 ...
- NOIp2018 TG day1 T2暨洛谷P5020 货币系统:题解
题目链接:https://www.luogu.org/problemnew/show/P5020 这道题感觉比较水啊,身为普及组蒟蒻都不费力的做出来了,而且数据范围应该还能大一些,n起码几万几十万都不 ...
- noip2018 洛谷 P5020 货币系统
关键: 要使m最小,(m,b)中的数不能用(n,a)中的数表示出来 对于 3 19 10 6 19=10+3+3+3 6=3+3 只有3 和 10 不能被(n,a)中的数表示 所以m=2 只需要 ...
随机推荐
- Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2) E. The Supersonic Rocket
这道题比赛之后被重新加了几个case,很多人现在都过不了了 算法就是先求凸包,然后判断两个凸包相等 我们可以吧凸包序列化为两点距离和角度 角度如果直接拿向量的叉积是不对的,,因为钝角和锐角的叉积有可能 ...
- List Leaves 树的层序遍历
3-树2 List Leaves (25 分) Given a tree, you are supposed to list all the leaves in the order of top do ...
- 爬虫2.5-scrapy框架-下载中间件
目录 scrapy框架-下载中间件 scrapy框架-下载中间件 middlewares.py中有两个类,一个是xxSpiderMiddleware类 一个是xxDownloaderMiddlewar ...
- 斯坦福大学机器学习(Andrew Ng@2014)--自学笔记
今天学习Andrew NG老师<机器学习>之6 - 6 - Advanced Optimization,做笔记如下: 用fminunc函数求代价函数最小值,分两步: 1.自定义代价函数 f ...
- New begin
Purpose 今天更换了id,希望重新沉淀. 晚上看到国外一个博客,落款有个中文: 敬惜字纸. 共勉.
- 4个数的和为0 51nod 1267
给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No". Input 第1行,1个数N,N为数组的长度(4 < ...
- 欢迎来怼第二周Scrum会议六(总第十三次)
一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/25 17:19~17:35(总计16min).地点:东 ...
- 03 JAVA IO
java.io包中定义了多个流类型来实现输入输出功能,以不同的角度进行分类: 按数据流的方向不同可以分为输入流和输出流 按处理数据单位不通可以分为字节流和字符流 按照功能不同可以分为节点流和处理流 所 ...
- Hadoop环境搭建01
根据马士兵老师的Hadoop进行的配置 1.首先列下来需要用到的软件 VirtulBox虚拟机.Centos7系统镜像.xshell.xftp.jdk安装包.hadoop-2.7.0安装包 2.在Vi ...
- 404 Note Found队——现场编程
目录 组员职责分工 github 的提交日志截图 程序运行截图 程序运行环境 GUI界面 基础功能实现 运行视频 LCG算法 过滤(降权)算法 算法思路 红黑树 附加功能一 背景 实现 附加功能二(迭 ...