题意:

        给定n种砝码,重量互不相等。

        每种砝码对应的数量为 
        现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。


        注:称重重量包括 0 。



方法一:
动态规划

思路:
        转化为01背包问题。

        将 砝码之和 即看成 背包的体积,又看成 背包装载的价值。
        当 增加的价值==消耗的体积 时,即恰满足条件,答案计数加一。

#include <bits/stdc++.h>

using namespace std;
int a[15],b[15],dp[1000005];

int main(){
    int n;
    while(cin >> n){
        memset(dp,0,sizeof(dp));
        int sum=0;
        for(int i=0;i<n;i++)//每种砝码的重量
            cin >> a[i];
        for(int i=0;i<n;i++)//每种砝码的数量
            cin >> b[i],sum+=b[i]*a[i];//sum统计砝码的重量总和
        for(int i=0;i<n;i++){
            for(int j=0;j<b[i];j++){
                for(int k=sum;k>=a[i];k--){//01背包
                    dp[k]=max(dp[k],dp[k-a[i]]+a[i]);
                }
            }
        }
        int res=0;
        for(int i=0;i<=sum;i++)
            if(dp[i]==i)//如果价值等于空间,则满足条件
                res++;
        cout << res << endl;
    }
    
    return 0;
}


时间复杂度:
空间复杂度:

方法二:
set去重

思路:
       利用set去重的思想。
        首先,set集合初始化:一个元素0。
        遍历每一个砝码,将集合中的数值都加上这个砝码的重量。
        因为集合有去重的功能,所以最后集合的大小即为答案。

        

#include <bits/stdc++.h>

using namespace std;
int a[15],b[15];

int main(){
    int n;
    while(cin >> n){
        for(int i=0;i<n;i++)
            cin >> a[i];//每种砝码的重量
        for(int i=0;i<n;i++)
            cin >> b[i];//每种砝码的数量
        
        unordered_set<int> res;
        res.insert(0);//初始化
        for(int i=0;i<n;i++){
            for(int j=0;j<b[i];j++){//遍历每个砝码
                unordered_set<int> t(res);
                for(auto x:t){
                    res.insert(x+a[i]);//添加并去重
                }
            }
        }
        cout << res.size() << endl;
    }
    
    return 0;
}

时间复杂度:
空间复杂度: