Problem - A - Codeforces
Problem - B - Codeforces
很难绷的一道题
让你计算多集合的数量。
首先,很明显的一点。这道题和数无关,只和数的数量有关。
比如 1 1 1 1 2 2 2 3 3 4和2 2 2 2 3 3 3 4 4 1 等价。
然后,我们可以这么依次对每个数进行处理。我们考虑每个数是作为特征数还是非特征数。
那么特征数会覆盖掉非特征数。
我们可以 一个一个数的往下递推。
比如我们看1,可以先分为特证数和非特征数。
如
1 1 1 1
我们考虑先不分组,那么1的分配有5种
但是很容易发现,如果我们把1全放在特证数上。
1111,我们这种情况加上分组则可以为s提供1的各种数量(0除外),而且这样的话,为之后的数提供了更多隐藏的位置,更优。
所以每次我们都只用考虑(0,cnt)和(cnt,0)的情况。
然后就可以考虑背包。
int n,a[N],cnt[N],maxl,f[N];
inline void clear(){up(i,1,n)a[i]=0;up(i,1,n)f[i]=0;maxl=0;up(i,1,n)cnt[i]=0;
}
signed main(){int T;cin>>T;while(T--){clear();cin>>n;up(i,1,n){cin>>a[i];cnt[a[i]]++;maxl=max(maxl,cnt[a[i]]);}f[0]=1;up(i,1,n){if(cnt[i]){dn(j,n,cnt[i]){f[j]=(f[j]+cnt[i]*f[j-cnt[i]])%mod;}}}int ans=0;for(int i=maxl;i<=n;i++)ans=(ans+f[i])%mod;cout<<ans<<endl;}return 0;
}