题意:给出n门课程,每一门课程考的分数,每一门课程的学分,求最多删去k组数据之后能够得到的最大加权平均数
先开一个数组x[],其中x[i]=1代表没有删除这门课程,x[i]=0表示删除了这门课程
然后p[i]=R*c[i]-c[i]*s[i]=c[i]*(R-s[i])
又因为满分为100分,就在0.0在100.0二分来找 再将p数组降序排列,ans为其前n-k个数的和, 如果ans-0>eps,那么l=mid, 如果ans-0<eps,那么r=mid
因为p[]数组是按照降序排列的,所以ans应该是递减的,大概是像这幅图一样
下面是学习的代码---------------
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std; 12 13 typedef long long LL; 14 const int INF = (1<<30)-1; 15 const int mod=1000000007; 16 const int maxn=1000005; 17 double eps=1e-4; 18 19 int s[maxn],c[maxn]; 20 double p[maxn]; 21 22 bool cmp(double a,double b){ 23 return a>b; 24 } 25 26 int main(){ 27 int ncase; 28 // freopen("in.txt","r",stdin); 29 // freopen("out.txt","w",stdout); 30 scanf("%d",&ncase); 31 for(int t=1;t<=ncase;t++){ 32 int n,k; 33 scanf("%d %d",&n,&k); 34 for(int i=1;i<=n;i++) scanf("%d",&s[i]); 35 for(int i=1;i<=n;i++) scanf("%d",&c[i]); 36 37 double l=0.0,r=100.0,mid; 38 39 while((r-l)>eps){ 40 mid=(l+r)/2; 41 42 for(int i=1;i<=n;i++) p[i]=(double)c[i]*(double)(s[i]-mid); 43 44 sort(p+1,p+n+1,cmp); 45 46 double ans=0.0; 47 for(int i=n-k;i>=1;i--) ans+=p[i]; 48 49 if(ans-0>eps) l=mid; 50 else r=mid; 51 } 52 53 printf("Case #%d:\n",t); 54 printf("%.3lf\n",mid); 55 } 56 return 0; 57 }
时间: 2024-10-22 22:57:18