zoukankan      html  css  js  c++  java
  • USACO 4.1.1 麦香牛块 Beef McNuggets

    题目大意

    给你(n)个数(a_1, a_2 ... a_n), 要你求最大的正整数(m)使得方程(a_1 x_1 + a_2 x_2 + ... + a_n x_n = m)无非负整数解. 题目数据满足(a_x)为正整数且不大于(256), (n le 10).

    Solution

    先看一个定理: 对于正整数(p), (q)满足(gcd(p, q) = 1), 我们有(px + qy = n)无非负整数解的最大正整数(n)(pq - p - q). 证明如下:
    我们首先利用反证法, 证明(px + qy e pq - p - q): 我们假设存在正整数(x)(y)使得(px + qy = pq - p - q), 则有

    [px + qy = pq - p - q \ p(x + 1) + q(y + 1) = pq \ ecause gcd(p, q) = 1且p | q(y + 1) \ herefore p | y + 1 \ 同理, q | x + 1 ]

    接着我们令(y + 1 = pj), (x + 1 = qk). 则有

    [pqk + qpj = pq \ pq(j + k) = pq ]

    注意到(x, y ge 0), 我们有(y + 1 ge 1)(x + 1 ge 1), 因而(j ge 1)(k ge 1). 因而(j + k ge 2), 因而假设不成立.
    得证.
    再证明当(n ge pq - p - q + 1)时原方程总有非负整数解:
    我们令(n = pq - p - q + k), 则根据扩展欧几里得定理, 方程(pa + qb = k)有整数解(其中(a)(b)中必有一个为正, 一个为负). 我们假设(a < 0 < b), 调整(a)(b)的值使得(|a| < q). 令此时的(a)(b)分别为(A)(B).
    回到原方程

    [px + qy = pq - p - q + k \ px + qy = pq - p - q + Ax + By \ p(x + 1 - A) + q(y + 1 - B) = pq ]

    根据前面的结论, 我们又有

    [p | y + 1 - B \ q | x + 1 - A ]

    因此我们令

    [j = frac{x + 1 - A} q \ k = frac{y + 1 - B} p ]

    则有

    [pq(i + j) = pq \ i + j = 1 ]

    不妨设(i = 0)(j = 1), 则

    [egin{cases} y + 1 - B= 0 \ x + 1 - A = q end{cases} ]

    因而

    [y = B - 1 \ x = A + q - 1 ]

    由于(B > 0), 因而(B - 1 ge 0);
    根据之前定义, 我们又有(|A| < q), 因而(A + q - 1 ge 0)
    因而原方程必有非负整数解.

    好了, 现在考虑这道题怎么做233
    注意到(a)值较小, 我们直接从0开始到(256^2)背包暴力即可.
    我们注意到(a)之间并不一定互质, 但这并不影响我们枚举的范围.

    #include <cstdio>
    #include <cctype>
    
    const int N = 10, LIM = 256;
    int a[N], f[LIM * LIM << 2];
    int main()
    {
        int n; scanf("%d", &n);
        for(int i = 0; i < n; ++ i) scanf("%d", a + i);
        f[0] = 1;
        for(int i = 1; i < LIM * LIM << 2; ++ i) for(int j = 0; j < n; ++ j) if(i - a[j] >= 0 && f[i - a[j]])  f[i] = 1;
        int ans = 0;
        for(int i = 1; i < LIM * LIM << 2; ++ i) if(! f[i]) ans = i;
        printf("%d
    ", ans > LIM * LIM ? 0 : ans);
    }
    
    
  • 相关阅读:
    ORACLE不常用但实用的技巧- 树查询 level用法
    oracle的start with connect by prior如何使用
    Oracle SQL日期及日期格式获取命令
    2019年起一般纳税人和小规模纳税人的区别
    10.pandas的替换和部分替换(replace)
    pandas中.value_counts()的用法
    Python模块/包/库安装几种方法(转载)
    预处理数据的方法总结(使用sklearn-preprocessing)
    python时间序列分析之_用pandas中的rolling函数计算时间窗口数据
    BZOJ2007 [Noi2010]海拔
  • 原文地址:https://www.cnblogs.com/ZeonfaiHo/p/7467060.html
Copyright © 2011-2022 走看看