• 洛谷 P5020 货币系统


    题目传送门

    解题思路:

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

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

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

     AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 
     6 using namespace std;
     7 
     8 int t,n,a[101],ans;
     9 bool f[25001];
    10 
    11 void solve() {
    12     scanf("%d",&n);
    13     for(int i = 1;i <= n; i++)
    14         scanf("%d",&a[i]);
    15     ans = n;
    16     sort(a+1,a+n+1);
    17     memset(f,0,sizeof(f));
    18     f[0] = 1;
    19     for(int i = 1;i <= n; i++) {
    20         if(f[a[i]]) ans--;
    21         for(int j = a[i];j <= a[n]; j++) 
    22             f[j] = f[j] | f[j-a[i]];
    23     }
    24     printf("%d
    ",ans);
    25 }
    26 
    27 int main() {
    28     scanf("%d",&t);
    29     for(int i = 1;i <= t; i++) 
    30         solve();
    31     return 0;
    32 }

    //NOIP提高 2018 Day1 T2

  • 相关阅读:
    TS之类的继承
    TS之函数及函数传参
    TS之数据类型
    Linux 协程
    设计模式 装饰器模式和代理模式
    C/C++ C和C++的区别
    C/C++ 内存分配方式
    Linux 进程间通信
    C/C++ RTTI
    Reactor设计模式
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11267286.html
Copyright © 2020-2023  润新知