比赛链接:Contest Setting C题
题意:$n$道题目,每道题目难度为$ai$,选择$k$道难度不同的题目,有多少种选择方案。$1<=k<=n<=1000,1<=ai<=10^9$
题解:问题转化一下(map,离散化均可):m种难度,每种难度有bi道题目,每次从m种中选择k种,把对应的题目数量相乘,求总和。
列出$dp[i][j]$:表示前j个物品以j结尾选择i个的方案数;$sum[i][j]$:表示从1-j分别作为结尾选择i个的方案数总和。
$dp[i][j]=b[j]*sum[i-1][j-1]$
$sum[i][j]=sum[i][j-1]+dp[i][j]$
1 #include <map> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 9 const int N=1e3+10; 10 typedef long long ll; 11 const ll mod=998244353; 12 map <ll,ll> m; 13 vector <ll> v; 14 ll b[N],dp[N][N],sum[N][N]; 15 16 int main(){ 17 int n,k; 18 ll x; 19 scanf("%d%d",&n,&k); 20 for(int i=1;i<=n;i++){ 21 scanf("%lld",&x); 22 if(m[x]==0) v.push_back(x); 23 m[x]++; 24 } 25 n=v.size(); 26 for(int i=1;i<=n;i++) b[i]=m[v[i-1]]; 27 for(int i=1;i<=n;i++) dp[1][i]=b[i]%mod,sum[1][i]=(dp[1][i]+sum[1][i-1])%mod; 28 for(int i=2;i<=k;i++){ 29 for(int j=1;j<=n;j++){ 30 dp[i][j]=(b[j]*sum[i-1][j-1])%mod; 31 sum[i][j]=(dp[i][j]+sum[i][j-1])%mod; 32 } 33 } 34 printf("%lld\n",sum[k][n]); 35 return 0; 36 }