洛谷 p5020 货币系统 题解
一个手动枚举能过一半点而且基本靠数学的题目(然而我考试的时候只有25分)
读清题目后发现就是凑数嘛,....
对啊,就是凑数,怎么凑是重点啊..
于是就绝望了一小时手动枚举n从1到5的情况
吐槽完毕,开始分析:
1.大的数只能由小的数凑出(好像是废话,但确实有用)
2.最小的数必须选
3.一个数的倍数也能凑出
4.一个数减去需要的数能被凑出的话这个数肯定能凑出(比如你有2,3,那么5-3=2,如果2可以凑出那么5也可以凑出)
5.除此以外在没有可以凑出的数
交代码
#include<bits/stdc++.h> using namespace std; int a[101],o,v[250001],ans; int main() { // freopen("money20.in","r",stdin); // freopen("1231231.out","w",stdout); int t; scanf("%d",&t); for(int pop=1; pop<=t; pop++) {//测t组数据 memset(a,0,sizeof a);//初始化 memset(v,0,sizeof v); int n; scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); sort(a+1,a+n+1);//排序,很重要为什么请看刚刚列的第1条 for(int i=1; i<=n; i++) { if(v[a[i]]==0)//第一个数或凑不出来的数必须选 ans++; for(int j=1;; j++) {倍数,第3条 o=j*a[i]; if(o<=a[n])//大于最大的数没必要算 v[o]=1; else break; } for(int j=a[i]; j<=a[n]; j++) { if(v[j-a[i]]==1)//减数第4条 v[j]=1; } } cout<<ans<<endl;//第5条 ans=0;//清空 } return 0; }
作者: liuzitong
出处:http://www.cnblogs.com/lztzs/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。