习题:The Unbearable Lightness of Weights(背包)

题目

传送门

思路

因为要确定砝码的重量,所以一定是确定一堆重量相同的砝码的重量

考虑\(dp[i]\)表示总重量为i的方案总数,之后重量相同的用组合数来算,看是否相等

当然有一种特殊情况,只有两种重量,

代码

#include<iostream>
using namespace std;
const int mod=1e9+7;
int n;
int a[105],limit,tot;
int dp[105][10005];//用i个砝码构成重量为j的方案
int s[105],ans;
long long qkpow(int a,int b)
{
    if(b==0)
        return 1;
    if(b==1)
        return a;
    long long t=qkpow(a,b/2);
    t=t*t%mod;
    if(b%2==1)
        t=t*a%mod;
    return t;
}
int calc(int n,int m)
{
    long long ret=1;
    for(int i=1;i<=m;i++)
        ret=ret*(n-i+1)%mod*qkpow(i,mod-2)%mod;
    return ret;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        s[a[i]]++;
        limit+=a[i];
        if(s[a[i]]==1)
            tot++;
    }
    if(tot==2)
    {
        cout<<n;
        return 0;
    }
    dp[0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=limit;j>=a[i];j--)
            for(int k=1;k<=i;k++)
                dp[k][j]=(dp[k][j]+dp[k-1][j-a[i]])%mod;
    for(int i=1;i<=100;i++)
        for(int j=1;j<=s[i];j++)
            if(dp[j][j*i]==calc(s[i],j))
                ans=max(ans,j);
    cout<<ans;
    return 0;
}
posted @ 2020-08-24 19:17  loney_s  阅读(166)  评论(0)    收藏  举报