• [USACO4.1]麦香牛块Beef McNuggets


    https://www.luogu.org/problemnew/show/P2737

    给出n个数ai,求这n个数不能累加出的最大的数

    最大的数无限大或能凑出所有的自然数则输出0

    n<=10,ai<=256

    结论一:

    给出两个数a,b

    若a,b 能凑出大于某个数的所有自然数

    那么由a的倍数组成的数必定能构成模b的完全剩余系

    否则 由a的倍数组成的数 不能构成模b的完全剩余系

    证明:

    若由a的倍数组成的数能构成模b的完全剩余系

    那么存在 k1,k2,…… kb 满足 ki*a%b 互不相同

    即 ax-by=p  

    对于 任意的p∈[0,b-1] 一定有x,y 的非负整数解

    而由扩展欧几里得定理得

    若gcd(a,b)= d

    则 ax+by=k*d 一定有整数解,

    且一定存在一组解,满足x∈[0,b/d-1],y∈[-a/d+1,0]

    所以

    若a,b互质,即gcd(a,b)= 1 ,p 必定是1的倍数,所以 由x个a,-y个b,可以凑出%b=p,p∈[0,b-1]的任意数

    若a,b不互质,则gcd(a,b)= d,那么只能凑出满足p%d=0 的数

    结论二:

    若gcd(a,b)=1 ,那么由a,b 不能凑出的最大的数为 a*b-a-b

    证明:

    1、 由结论一得,a,b 一定存在不能凑出的最大的数

    2、证明这个最大的数为 a*b-a-b,即noip2017 day1 t1

    参见http://www.cnblogs.com/TheRoadToTheGold/p/8214630.html

    所以本题解法:

    先判断给出的n个数gcd是否等于1,不等于1则不等凑出的数无穷大,输出0

    然后dp[i] 表示数i能否被凑出来,做一遍完全背包即可

    从里面找出不能凑出的最大的数

    #include<cstdio>
    
    using namespace std;
    
    #define N 256*256
    
    bool dp[N+1];
    int a[11];
    
    int getgcd(int a,int b) { return !b ? a : getgcd(b,a%b); }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        int gcd=0;
        for(int i=1;i<=n;++i) 
        {
            scanf("%d",&a[i]);
            gcd=getgcd(a[i],gcd);
        }
        if(gcd!=1)
        {
            printf("0");
            return 0;
        }
        dp[0]=true;
        for(int i=1;i<=n;++i)
            for(int j=a[i];j<N;++j)
                dp[j]|=dp[j-a[i]];
        for(int i=N-1;i>=0;--i)
            if(!dp[i]) { printf("%d",i); return 0; }
        printf("0");
    }
  • 相关阅读:
    剑桥雅思写作高分范文ESSAY81
    maven安装配置
    IntelliJ IDEA 2017.3.1安装步骤
    Git基本命令整理
    jacoco覆盖率工具测试及性能分析
    OSGI框架
    查看指定库对应GCC版本
    普元eos、soa、esb
    emp架构
    jar包安装到本地仓库
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8227667.html
Copyright © 2020-2023  润新知