题解 | 称砝码
称砝码
https://www.nowcoder.com/practice/f9a4c19050fc477e9e27eb75f3bfd49c
由于砝码的种类数较少,每种砝码的数量也不大,可以使用“暴力”方法来枚举所有可能的重量。
首先,使用一个 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;
}
美的集团公司福利 719人发布