容易证明,这道题最多六位小数,精度不是问题,然而我这份代码却有万分之2的差异一直调不出来,已排除精度误差,求调。
#include<cstdio>
int n,a,b,numa[2010],numb[2010];
double pt[2010],cj[2010];
long double dp[2010],l1=0,r1=1,l2,r2,mid,mid2,eps=1e-10;
bool check2(long double ca,long double cb){
for(int i=1;i<=n;i++){
dp[i]=dp[i-1],numa[i]=numb[i]=0;
if(dp[i]<dp[i-1]+pt[i]-eps-ca)dp[i]=dp[i-1]+pt[i]-ca,numa[i]=1;
if(dp[i]<dp[i-1]+cj[i]-eps-cb)dp[i]=dp[i-1]+cj[i]-cb,numb[i]=1,numa[i]=0;
if(dp[i]<dp[i-1]+cj[i]+pt[i]-cj[i]*pt[i]-eps-ca-cb)
dp[i]=dp[i-1]+pt[i]+cj[i]-pt[i]*cj[i]-ca-cb,numa[i]=numb[i]=1;
numb[i]+=numb[i-1],numa[i]+=numa[i-1];
}
return numb[n]>b;
}
bool check(long double ca){
l2=0,r2=1;
for(int i=1;i<=50;i++){
mid2=(l2+r2)/2;
if(check2(ca,mid2))l2=mid2;
else r2=mid2;
}
return numa[n]>a;
}
int main(){
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++)scanf("%lf",pt+i);
for(int j=1;j<=n;j++)scanf("%lf",cj+j);
for(int i=1;i<=50;i++){
mid=(l1+r1)/2;
if(check(mid))l1=mid;
else r1=mid;
}
check2(l1,l2);
printf("%.6Lf\n",dp[n]+l1*a+l2*b);
return 0;
}
CF第17组数据有万分之了零点九的差异
41 8 22
0.173 0.359 0.996 0.098 0.739 0.941 0.489 0.622 0.314 0.932 0.950 0.080 0.383 0.346 0.729 0.456 0.590 0.455 0.159 0.900 0.700 0.128 0.675 0.954 0.703 0.646 0.757 0.197 0.474 0.957 0.225 0.426 0.652 0.616 0.677 0.707 0.645 0.854 0.102 0.908 0.924
0.307 0.174 0.225 0.196 0.965 0.865 0.044 0.976 0.874 0.089 0.783 0.527 0.840 0.165 0.914 0.095 0.702 0.657 0.246 0.773 0.806 0.011 0.810 0.302 0.033 0.779 0.036 0.767 0.428 0.585 0.420 0.412 0.763 0.180 0.119 0.108 0.587 0.254 0.162 0.210 0.588
Output
22.63400000
Answer
22.63200000000000145
求调QWQ