NC25660. 选数字
描述
给一个长为 n 的序列 ,从中等概率选出 k 个下标不同的数字,求最小值的期望值。
不难发现期望值乘以之后是一个整数,你只需要输出这个整数对 1000000007 取模后的结果。
这里表示从 n 个数中无序选出 k 个数的方案数,也就是组合数。
输入描述
第一行是一个正整数,表示测试数据的组数,
对于每组测试数据,
第一行是两个正整数 ,分别表示序列长度以及选出的数字个数。
第二行包含n个整数。
输出描述
对于每组测试数据,输出一行,包含一个整数,表示期望值乘以之后对 1000000007 取模的结果。
示例1
输入:
1 5 2 1 2 3 4 5
输出:
20
C++14(g++5.4) 解法, 执行用时: 9ms, 内存消耗: 4452K, 提交时间: 2019-05-12 14:10:15
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; int a[1005],c[1005][1005]; int main() { int t; scanf("%d",&t); for(int i=0;i<1005;i++) c[i][0]=1; for(int i=1;i<1005;i++) for(int j=1;j<=i;j++) c[i][j] =(c[i-1][j]+c[i-1][j-1])%1000000007; while(t--) { int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); long long int out = 0; for(int i=1;i<=n;i++) if(k-1<=n-i) { out+=a[i]*c[n-i][k-1]; out%=1000000007; } printf("%lld\n",out); } return 0; }
C++(clang++ 11.0.1) 解法, 执行用时: 14ms, 内存消耗: 8436K, 提交时间: 2023-03-23 18:15:57
#include<bits/stdc++.h> using namespace std; int a[1010]; long long m[1010][1010]; void f() { for(int i=0;i<1010;i++) { m[0][i]=0; m[i][0]=1; } for(int i=1;i<1010;i++) for(int j=1;j<1010;j++) m[i][j]=(m[i-1][j-1]+m[i-1][j])%1000000007; } int main() { f(); int t; cin>>t; while(t--){ int n,k; cin>>n>>k; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); long long sum=0; for(int i=0;i<n;i++) { if(n-i-1<k-1) break; sum+=(a[i]*m[n-i-1][k-1]); sum%=1000000007; } cout<<sum<<endl;; } return 0; }