1. 程式人生 > 實用技巧 >習題:The Unbearable Lightness of Weights(揹包)

習題: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;
}