由于砝码的种类数较少,每种砝码的数量也不大,可以使用“暴力”方法来枚举所有可能的重量。

首先,使用一个 map<int, int, greater<int>>(或其他合适的数据结构)记录当前可以到达的重量集合,初始时包含重量 0。

这里使用 greater 是因为方便我直接使用 auto 进行从大到小的遍历,如果从小到大就变成完全背包了

对于第 i 种砝码,数量为 x[i],其重量为 m[i]。我们将它能够产生的新重量全部加入现有集合中,即:在当前所有可行重量基础上,累加 m[i] 一次,直到累加 x[i] 次,得到所有新的可行重量。

每次生成的新重量,都要并入已有集合(即合并到 mp)中。

最终,mp 中记录了所有可以用砝码组合得到的重量(包括 0)。mp.size() 即为不同重量的总数

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
int __t = 1, n, m, x;
void solve() {
    cin >> n;
    map<int, int, greater<int>> mp;
    mp[0] = 1;
    vector<int> m(n), x(n);
    for (int i = 0; i < n; i++)
        cin >> m[i];
    for (int i = 0; i < n; i++)
        cin >> x[i];
    for (int i = 0; i < n; i++)
        for (int j = 1; j <= x[i]; j++) {
            map<int, int, greater<int>> dmp;
            for (auto [k, v] : mp)
                dmp[k + m[i]] = 1;
            for (auto [k, v] : dmp)
                mp[k] = 1;
        }
    cout << mp.size() << '\n';
    return;
}
int32_t main() {
#ifdef ONLINE_JUDGE
    ios::sync_with_stdio(false);
    cin.tie(0);
#endif
    // cin >> __t;
    while (__t--)
        solve();
    return 0;
}

 每日一题攒牛币,大厂offer不是梦,点我马上开始赚牛币

#牛客春招刷题训练营#