Loading

[LQ17] 包子凑数

题目链接

题意

\(N\) 个数,每个数的数量任意多,不能组成的数有多少

分析

  • 考虑一个简单的情形,面值为 \(x, y, z\) 的三种纸币,能组成 i 元的必要条件是能组成 i-xi-yi-z 元,我们用 dp[i] 来表示是否能组成 i 元,因为 0 元肯定能取到,所以有 dp[0]=1
  • 再者,如果纸币的最大公约数不为1,我们记其最大公约数为 gcd,那么其只能组成 gcd 的倍数的面额,不能组成的数有无穷多个

代码

#include <stdio.h>
#define N 105
#define MAX 100000
int dp[MAX];  // 能否取到包子
int a[N];   // 能装的包子数

int gcd(int a, int b) {
    return (a % b == 0) ? b : gcd(b, a % b);
}

int main(int argc, const char * argv[]) {
    
    int n;
    scanf("%d", &n);
    
    int i, j, g;
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    // 所有数的最大公约数
    g = gcd(a[0], a[1]);
    for (i = 2; i < n; i++) {
        g = gcd(g, a[i]);
    }
    if (g > 1) {
        printf("INF\n");
    } else {
        dp[0] = 1;  // 0个包子
        for (i = 0; i < n; i++) {
            for (j = 0; j + a[i] < MAX; j++) {
                if (dp[j]) {
                    dp[j + a[i]] = 1;
                }
            }
        }
        int sum = 0;
        for (i = 0; i < MAX; i++) {
            if (!dp[i]) {
                sum++;
            }
        }
        printf("%d\n", sum);
    }
    
    return 0;
}
posted @ 2025-03-09 20:08  Chase_Tsai  阅读(1)  评论(0)    收藏  举报