zoukankan      html  css  js  c++  java
  • 2018D1T2 货币系统

    2018D1T2 货币系统

    problem

    记货币种类为(n),面额数组为(a[1...n])的货币系统为((n,a))。货币系统((n,a))((m,b))等价,当且仅当对于(forall xin mathbf N)(x)要么均可以被两个货币系统表示,或者不能被任何一个表示。
    给定一个货币系统((n,a)),求与其等价的货币系统((m,b)),并使(m)尽可能小。

    solution

    我们把货币系统((n,a))看做集合(A),货币系统((m,b))看做集合(B),我们猜测(B⊆ A),接下来进行证明。

    一些奇奇怪怪的证明

    证明1(A)集合内不能被其他数表示的数必然存在于(B)集合内。
    证明:我们设(xin A)(x)不能被(A)集合中除他以外的元素表示出来。(即(forall Y⊆A,exists xin A,x otin T,x eq sumlimits_{ain T} a)
    我们假设(x otin B),由于两个集合等价,所以(B)集合一定能够表示出(x),换句话说(exists X⊆B,x=sumlimits_{bin X}b)

    那么(X)集合中的元素中至少有一个不在(A)内,并且不能被集合(A)里的元素组成(因为如果不存在的话(A)内的元素就可以表示(x)了)。这样与(B)集合的定义产生矛盾。这样我们可以证明。
    证明2(B⊆A)
    证明:假设(exists xin B,x otin A)
    根据题目条件,(x)一定可以被(A)集合内的数字所组成。那么必然(exists U⊆A,U={a_i})可以用来组成(x)并且这些元素都不能被(A)集合内的元素组成(因为如果(a_i)能被(A)集合内其他数组成,那么必然可以用那些数来代替(a_i)),根据上一个结论我们知道(U⊆B).
    那么也就是说(x)可以被(B)集合内的数字组成,那么凡是可以用(x)组成的数都可以被(B)集合内的其他数字组成,那么也就是说即便从集合(B)中去掉(x)元素也依旧满足条件,这就与(B)集合的定义矛盾。
    所以(forall xin B,xin A iff B⊆A)

    算法

    最后:(A)集合中,能被其他数组成的数必然不在(B)集合内
    到这里,我们只需要计算出(A)集合内存在多少个能被其他数计算出来的就行了。
    使用完全背包。
    根据常识,我们知道(x)只能被他小的数字组成。
    我们对数组排个序,然后对于每一个数考虑能不能被它前面的数字所组成。我们知道如果(x)能够被前(i)个数字组成,并且组成(x)的数中包含(a_i),那么(x-a_i)也可以用前(i)个数来组成。那么我们很容易想到定义(f(x))表示(x)能否被组成,则(f(x)=f(x)∨f(x-a_i))

    code

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    #define MAXAI 25005
    #define MAXN 105
    int f[MAXAI];
    int a[MAXN];
    int main()
    {
        int i,j,n,T,ans;
        scanf("%d",&T);
        while(T--)
        {
            memset(f,0,sizeof(f));
            scanf("%d",&n);ans=n;
            for(i=1;i<=n;i++) scanf("%d",&a[i]);
            sort(a+1,a+n+1);
            f[0]=1;
            for(i=1;i<=n;i++)
            {
                if(f[a[i]])
                {
                    ans--;
                    continue;
                }
                for(j=a[i];j<=a[n];j++)
                {
                    f[j]=f[j]|f[j-a[i]];
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    使用eclipse阅读java源码
    找重复值
    mysql获取表中数据行数
    DBArtist之Oracle入门第2步: 了解Oracle的Database Control
    DBArtist之Oracle入门第1步: 如何安装Oracle 11g
    存储过程中使用事务和try catch
    Mysql设置auto_increment_increment和auto_increment_offset
    SQL SERVER性能优化综述
    Sql Server 2008R2 数据库发布与订阅
    无法修改SQL Server 服务名称
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/2018d1t2.html
Copyright © 2011-2022 走看看