The Unbearable Lightness of Weights (多重背包+STL)

                        The Unbearable Lightness of Weights 

You have a set of nn weights. You know that their masses are a1, a2, ..., anan grams, but you don't know which of them has which mass. You can't distinguish the weights.

However, your friend does know the mass of each weight. You can ask your friend to give you exactly k weights with the total mass m (both parameters k and mm are chosen by you), and your friend will point to any valid subset of weights, if it is possible.

You are allowed to make this query only once. Find the maximum possible number of weights you can reveal after this query.

Input

The first line contains a single integer n (1≤n≤1001≤n≤100) — the number of weights.

The second line contains nn integers na1,a2,…,an (1≤ai≤100) — the masses of the weights.

Output

Print the maximum number of weights you can learn the masses for after making a single query.

Input

4
1 4 2 2
2

Input

6
1 2 4 4 4 9
2

Note

In the first example we can ask for a subset of two weights with total mass being equal to 44, and the only option is to get {2,2}.

Another way to obtain the same result is to ask for a subset of two weights with the total mass of 55 and get {1,4}. It is easy to see that the two remaining weights have mass of 2 grams each.

In the second example we can ask for a subset of two weights with total mass being 8, and the only answer is {4,4}. We can prove it is not possible to learn masses for three weights in one query, but we won't put the proof here.

题意:

给你一个n表示物品的数量,然后跟着n个物品的重量,有一个k表示每次可以知道k个物品的重量的和,问你最大可以知道几个物品确切的重量

题解:

首先明确,这个k个物品的重量和一定是唯一的(即不存在其他组合与这k个物品的重量和相同),其次,若想要确切的知道物品的重量,知道的k个物品重量和的物品一定是相同的,这样才能保证知道每个物品的重量

总结一句话:要想知道物品的重量,则知道k个物品重量和的物品一定是相同的,并且他们这k个的和一定是唯一确定的(即不存在其他组合与这k个物品的重量和相同)

那么 k的最大值为同种物品的数量

应用多重背包即可

map<int,int>vis;

for(auto p:vis) v.push_back(p);
 遍历map 将map的第一维(种类)赋值给vector的first,map的第二维(个数)赋值给vector的second

for(auto p:vis)这是跑map的骚操作当然跑vector也可以


vector<pair<int,int> >v;
for(auto p:v) 与  for(int i=0;i<v.size();i++)等价

 vol=p.first;          vol=v[i].first;  

k=p.second;      k=v[i].second;

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+7;

int a[maxn],dp[maxn][105]; //多重背包 重量为i装j个物品的方案数
int main() //大佬的代码 Sheryang
{
    int n;
    scanf("%d",&n);
    map<int,int>vis;//标记数量

    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        vis[a[i]]++;
    }

    vector<pair<int,int> >v;
    for(auto p:vis) v.push_back(p);
    // 遍历map 将map的第一维(种类)赋值给vector的first,map的第二维(个数)赋值给vector的second

    dp[0][0]=1;

    for(auto p:v)//for(int i=0;i<v.size();i++)
    {
        int vol=p.first;
        int k=p.second; //多重背包基本套路
        for(int i=1e4;i>0;i--)//枚举背包重量
            for(int j=1;j<=n;j++)//枚举方案数
                for(int t=1;t<=k && t<=j && i-vol*t>=0;t++)
                {
                    dp[i][j]+=dp[i-vol*t][j-t];
                    dp[i][j]=min(dp[i][j],2);//防止爆int > 1 即可 用不用都行
                }
    }
    if(v.size()==2) //特判只有两种质量物品 
    {
          printf("%d\n",n);
          return 0;
    }

    //枚举同种物品的最大数量并且选此物品的方案数为1
    int ans=1;
    for(auto p:v)
    {
        int vol=p.first;
        int k=p.second;
        for(int i=1;i<=k;i++)
            if(dp[i*vol][i]==1) //方案唯一则可以判断
                ans=max(ans,i);
    }

    printf("%d\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值