蓝桥杯 7. 包子凑数

包子凑数

原题目链接

题目描述

小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 N 种蒸笼,其中第 i 种蒸笼恰好能放 Aᵢ 个包子。每种蒸笼都有非常多笼,可以认为是无限笼。

每当有顾客想买 X 个包子,卖包子的大叔就会迅速选出若干笼包子,使得这若干笼中恰好一共有 X 个包子。

例如:

  • 有 3 种蒸笼,分别能放 3、4 和 5 个包子。
  • 顾客想买 11 个包子时,大叔可以选 2 笼 3 个的再加 1 笼 5 个的(或 1 笼 3 个的加 2 笼 4 个的)。

当然,有时包子大叔无论如何也凑不出顾客想买的数量。

例如:

  • 有 3 种蒸笼,分别能放 4、5 和 6 个包子。
  • 顾客想买 7 个包子时,大叔就无法凑出。

小明想知道一共有多少种数目是包子大叔凑不出来的。


输入描述

  • 第一行包含一个整数 N (1 ≤ N ≤ 100),表示蒸笼种类数。
  • 接下来的 N 行中,每行一个整数 Aᵢ (1 ≤ Aᵢ ≤ 100),表示第 i 种蒸笼可以装的包子数。

输出描述

输出一个整数,表示无法凑出的包子数的个数。
如果无法凑出的数目有无限多个,则输出 INF


输入样例 1

2
4
5

输出样例 1

6

样例说明:

凑不出的数包括:1, 2, 3, 6, 7, 11


输入样例 2

2
4
6

输出样例 2

INF

样例说明:

所有奇数都无法凑出,因此凑不出的数目无限多。

c++代码

#include

using namespace std;

int main() {
    int n, cont = 0;
    cin >> n;
    vector<int> arr(n);
    for (int i = 0; i < n; i++) cin >> arr[i];
    vector<bool> dp(10002, false);
    dp[0] = true;
    for (int i = 1; i <= 10001; i++) {
        for (int j = 0; j < arr.size() && !dp[i]; j++) {
            if (i - arr[j] >= 0 && dp[i - arr[j]]) dp[i] = true;
        }
        if (!dp[i]) cont++;
    }
    if (!dp[10000] || !dp[10001]) cout << "INF";
    else cout << cont;
    return 0;
}//by wqs

思路解析

假设包子的每笼数量是a,b,c,d,e...
dp[i]表示i个包子可不可以通过组合得到,则dp[i] = dp[i - a] || dp[i - b] || dp[i - c] || dp[i - d] || dp[i - e].....
例如第一个测试样例dp[i] = dp[i - 4] || dp[i - 5]
注意如果一个很大的数不可以通过组合得到,我们就认为后面的数都不可以通过组合得到。
所以如果10000或者100001不能通过组合得到,我就认为后面的数全都不可以组合得到。

你可能感兴趣的:(蓝桥杯题库,蓝桥杯,算法,职场和发展,c++,数据结构)