博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P5020 货币系统
阅读量:5325 次
发布时间:2019-06-14

本文共 1335 字,大约阅读时间需要 4 分钟。

嗯...

 

题目链接:https://www.luogu.org/problem/P5020

 

题目简化:

给定一个货币系统,该货币系统中有n种不同面值的货币,第i种货币的面值是a_i,我们将这个货币系统记作(n,a)。定义一个面值x能被(n,a)表示,当且仅当存在一个非负整数序列t,满足:给定一个货币系统(n,a),求一个货币系统(m,b),使得(n,a)与(m,b)是等价的,且m尽可能小。

 

首先证明一个事实,最终求出的货币系统中的元素,一定出现在原来的货币系统中,也就是不存在原来货币系统之外的元素。 

证明:

那么显然的是,最终我们求得到的集合就是(n,a)中不能被其他数字表示的数的集合。并且我们发现,如果一个数能被表示,那么显然会被比它小的数表示。

 

思路:

所以我们可以把原来的货币按照面值升序排序,从小到大考虑每一个数,设f[i]为只用到当前考虑的数之前的数能否表述出数字i。那么对于当前数字,如果它能被前面的数表示,那么可以扔掉。否则,将它加入答案,并更新f数组(其实是一个类似背包的问题

 

AC代码:

1 #include
2 #include
3 #include
4 #include
5 6 using namespace std; 7 8 int a[25005], f[25005]; 9 10 int main(){11 int t, n;12 scanf("%d", &t);13 for(int i = 1; i <= t; i++){14 memset(a, 0, sizeof(a));15 memset(f, 0, sizeof(f));16 f[0] = 1;17 scanf("%d", &n);18 int ans = n;19 for(int j = 1; j <= n; j++)20 scanf("%d", &a[j]);21 sort(a + 1, a + 1 + n);22 for(int j = 1; j <= n; j++){23 if(f[a[j]]) ans--;24 for(int k = a[j]; k <= a[n]; k++){25 if(f[k] || f[k - a[j]]) f[k] = 1;//f[k] = f[k] | f[k - a[j]];26 }27 }28 printf("%d\n", ans);29 }30 return 0;31 }
AC代码

 

转载于:https://www.cnblogs.com/New-ljx/p/11267158.html

你可能感兴趣的文章
[poj1006]Biorhythms
查看>>
Hyper-V虚拟机上安装一个图形界面的Linux系统
查看>>
js千分位处理
查看>>
Mac---------三指拖移
查看>>
字符串类型的相互转换
查看>>
基础学习:C#中float的取值范围和精度
查看>>
javaagent 简介
查看>>
python升级安装后的yum的修复
查看>>
Vim配置Node.js开发工具
查看>>
web前端面试题2017
查看>>
ELMAH——可插拔错误日志工具
查看>>
MySQL学习笔记(四)
查看>>
【Crash Course Psychology】2. Research & Experimentation笔记
查看>>
两数和
查看>>
移动设备和SharePoint 2013 - 第3部分:推送通知
查看>>
SOPC Builder中SystemID
查看>>
MySQL数据库备份工具mysqldump的使用(转)
查看>>
NTP服务器配置
查看>>
关于 linux 的 limit 的设置
查看>>
HDU(4528),BFS,2013腾讯编程马拉松初赛第五场(3月25日)
查看>>