zoukankan      html  css  js  c++  java
  • [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");
    }
  • 相关阅读:
    fenby C语言 P32
    fenby C语言 P31 使用数组的指针
    fenby C语言 P30
    fenby C语言 P29
    fenby C语言 P28
    fenby C语言 P27使用指针
    fenby C语言 P25
    fenby C语言 P26
    fenby C语言P24
    Python学习之路:通过socket实现处理多个连接
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8227667.html
Copyright © 2011-2022 走看看