求助WQS二分
查看原帖
求助WQS二分
85593
dying楼主2021/11/1 21:27

容易证明,这道题最多六位小数,精度不是问题,然而我这份代码却有万分之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

2021/11/1 21:27
加载中...