C . Contest Setting(前i个分j组,每一组不能有重复的数字)
A group of contest writers have written nn problems and want to use kk of them in an upcoming contest. Each problem has a difficulty level. A contest is valid if all of its kk problems have different difficulty levels.
Compute how many distinct valid contests the contest writers can produce. Two contests are distinct if and only if there exists some problem present in one contest but not present in the other.
Print the result modulo 998,244,353
Input
The first line of input contains two space-separated integers nn and kk (1≤k≤n≤10001≤k≤n≤1000). The next line contains nn space-separated integers representing the difficulty levels. The difficulty levels are between 1 and 109109 (inclusive).
Output
Print the number of distinct contests possible, modulo 998,244,353.
Samples
12 5 3 1 4 1 5 9 2 6 5 3 5 8
316
题目大意:
这个题就是给你n个数,然后分成k组,然后每一组中不能有相同的数字,问你方案数?
题目解析:
这个题就是一个dp的问题:dp[i][j]为前i个数选择j组的方案数
然后这个转移方程就是:dp[i][j]=min(dp[i-1][j-1]*t[i].c%mod+dp[i-1][j])%mod,这个t[i].c为这个数的个数
#include<iostream> #include<algorithm> #include<queue> using namespace std; typedef long long ll; const int maxn=1e3+100; const int mod=998244353; ll dp[maxn][maxn];//前i个数选择j个数的 ll a[maxn]; struct node{ ll w; ll c; }t[maxn]; int main(){ int n,k; cin>>n>>k; for(int i=1;i<=n;i++){ cin>>a[i]; } sort(a+1,a+n+1); int cnt=1; t[cnt].w=a[1]; t[cnt].c=1; for(int i=2;i<=n;i++){ if(a[i]==a[i-1]){ t[cnt].c++; } else{ cnt++; t[cnt].w=a[i]; t[cnt].c=1; } } for(int i=0;i<=cnt;i++){ dp[i][0]=1; } for(int i=1;i<=cnt;i++){ for(int j=1;j<=k;j++){ dp[i][j]=(dp[i-1][j-1]*t[i].c%mod+dp[i-1][j])%mod; } } cout<<dp[cnt][k]<<endl; }