1. 程式人生 > >The Unbearable Lightness of Weights (多重揹包+STL)

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 即可 用不用都行
                }
    }
    //列舉同種物品的最大數量並且選此物品的方案數為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) //方案唯一則可以判斷
            {
                if(v.size()==2 && i==k) //特判只有兩種質量物品 
                {
                    printf("%d\n",n);
                    return 0;
                }
    
                else ans=max(ans,i);
            }
    }

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