题解 | #称砝码#
称砝码
https://www.nowcoder.com/practice/f9a4c19050fc477e9e27eb75f3bfd49c
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
while (cin >> n) {
vector<int> m(n,0);
vector<int> x(n,0);
set<int> s;
s.insert(0);
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 = 0; j < x[i]; j++) {
set<int> t(s);
for (auto it = t.begin(); it != t.end(); it++) {
s.insert(*it+m[i]);
}
// cout << s.size() << endl;
}
}
cout << s.size() << endl;
}
}
复制了一位大佬newcoder的题解:先计算可能的最大值sum,砝码总数len 则建立dp[len+1][sum+1] 表示第i号砝码之前能否凑出重量j 注意len不是类别的数量而是砝码的数量 之后就按照0-1背包思路dp,再设置一个unordered_set,当j被成功凑出后便加入集合 最后输出集合的大小(再额外加一个0)
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;
while(cin>>N){
vector<int> weight;
vector<int> mount;
int temp;
for(int i=0;i<N;i++){
cin>>temp;
weight.emplace_back(temp);
}
for(int i=0;i<N;i++){
cin>>temp;
mount.emplace_back(temp);
}
int sum=0;
for(int i=0;i<N;i++){
sum=sum+weight[i]*mount[i];
}
vector<int> Weight;
for(int i=0;i<N;i++){
for(int j=0;j<mount[i];j++){
Weight.emplace_back(weight[i]);
}
}
int len=Weight.size();
unordered_set<int> ok;
vector<vector<bool>> dp(len+1,vector<bool>(sum+1, false));
for(int i=0;i<len+1;i++){
dp[i][0]=true;
}
for(int i=1;i<len+1;i++){
for(int j=1;j<sum+1;j++){
if(Weight[i-1]>j){
dp[i][j]=dp[i-1][j];
}
else{
dp[i][j]=dp[i-1][j]||dp[i-1][j-Weight[i-1]];
}
if(dp[i][j]){
ok.insert(j);
}
}
}
cout<<ok.size()+1<<endl;
}
return 0;
}

