题目链接:http://abc057.contest.atcoder.jp/tasks/abc057_d
题意:给出n个数,可以选择x~y个数,使其平均值最大,求其最大平均数以及选择方案数。
思路:只考虑两种情况即可:
1. 最大的数出现次数大于x, 那么最大平均数及为最大数,选择方案数为C(b[0], i) x<=i<=min(y, b[0]); //其中b[0]为最大数出现的次数
2. 最大数出现的次数小于x, 那么我们只需要考虑最末尾那个数即可;
代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <stdio.h> 4 #define ll long long 5 #define MAXN 60 6 using namespace std; 7 8 ll a[MAXN], b[MAXN], c[MAXN][MAXN]; 9 10 void gelou(void){//组合模板 11 c[1][0]=c[1][1]=1; 12 for(int i = 2; i<MAXN; i++){ 13 c[i][0]=1; 14 for(int j = 1; j<MAXN; j++){ 15 c[i][j]=(c[i-1][j]+c[i-1][j-1]); 16 } 17 } 18 } 19 20 int main(void){ 21 gelou(); 22 ll n, x, y; 23 cin >> n >> x >> y; 24 for(int i=0; i<n; i++){ 25 cin >> a[i]; 26 } 27 sort(a, a+n); 28 ll pos=0, cc=a[n-1]; 29 for(int i=n-1; i>=0; i--){//记录每个数出现的次数 30 if(a[i]==cc){ 31 b[pos]++; 32 }else{ 33 cc=a[i]; 34 pos++; 35 b[pos]++; 36 } 37 } 38 pos++; 39 ll gg=0, num=0; 40 if(b[0]>=x){//最大的数出现的次数大于等于x 41 for(int i=x; i<=min(b[0], y); i++){ 42 num+=c[b[0]][i]; 43 } 44 printf("%.6lf ", (double)a[n-1]); 45 printf("%lld ", num); 46 return 0; 47 } 48 for(int i=0; i<pos; i++){ 49 if(gg+b[i]>=x){ 50 ll f=x-gg; 51 num=c[b[i]][f];//只考虑最后一个值的选择情况 52 break; 53 }else{ 54 gg+=b[i]; 55 } 56 } 57 double ave=0; 58 for(int i=n-1,j=0; j<x; j++,i--){ 59 ave+=a[i]; 60 } 61 ave/=x; 62 printf("%.6lf ", ave); 63 printf("%lld ", num); 64 return 0; 65 }