【CF739E】Gosha is Hunting-期望DP+WQS二分

测试地址:Gosha is Hunting
题目大意:n只精灵,有a个精灵球和b个大师球,用精灵球抓住精灵i的概率为pi,用大师球抓住精灵i的概率为qi,不能用两个或以上相同种类的球重复捕捉同一只精灵,问能捕捉到的精灵的最大期望数目。
做法:本题需要用到期望DP+WQS二分。
首先很快能想到一个DP:令f(i,a,b)为前i只精灵,用了a个精灵球,b个大师球的最大期望,我们只用考虑对于当前精灵,不用任何球,用精灵球,用大师球,精灵球和大师球都用四种情况转移即可。
然而这样是O(n3)的,显然无法通过。注意到题目中的限制有可能可以使用WQS二分,于是我们一看,f(i,a,b)在固定i,a是,关于b的函数是上凸的,因为显然用的球越多,产生的收益就越小。所以内层直接使用WQS二分,时间复杂度O(n2logC)
这样已经差不多可以通过此题了,但还有更好的做法。和上面同理,因为f(i,a,b)在固定i,b时,关于a的函数是上凸的,所以a这一维也可以使用WQS二分,这样时间复杂度就是O(nlog2C)的了,可以飞快地通过此题。
还有一点要注意,是这种涉及实数二分的题的常见问题,因为最优方案会突变,所以在最后选择左右端点上的方案时,选取使得最优的a,b更小的那个端点就能避免这个问题。
以下是本人代码:

#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
int n,a,b,numa[2010],numb[2010];
double p[2010],q[2010],f[2010];

int solve(double x,double y)
{
    f[0]=0.0,numa[0]=0,numb[0]=0;
    for(int i=1;i<=n;i++)
    {
        f[i]=f[i-1];
        numa[i]=numa[i-1];
        numb[i]=numb[i-1];
        if (f[i-1]+p[i]-x>f[i])
        {
            f[i]=f[i-1]+p[i]-x;
            numa[i]=numa[i-1]+1;
            numb[i]=numb[i-1];
        }
        if (f[i-1]+q[i]-y>f[i])
        {
            f[i]=f[i-1]+q[i]-y;
            numa[i]=numa[i-1];
            numb[i]=numb[i-1]+1;
        }
        if (f[i-1]+p[i]+q[i]-p[i]*q[i]-x-y>f[i])
        {
            f[i]=f[i-1]+p[i]+q[i]-p[i]*q[i]-x-y;
            numa[i]=numa[i-1]+1;
            numb[i]=numb[i-1]+1;
        }
    }
}

int main()
{
    scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;i++)
        scanf("%lf",&p[i]);
    for(int i=1;i<=n;i++)
        scanf("%lf",&q[i]);

    double l1=0.0,r1=1.0,l2,r2;
    while(r1-l1>eps)
    {
        double mid1=(l1+r1)/2.0;
        l2=0.0,r2=1.0;
        while(r2-l2>eps)
        {
            double mid2=(l2+r2)/2.0;
            solve(mid1,mid2);
            if (numb[n]>b) l2=mid2;
            else r2=mid2;
        }
        solve(mid1,r2);
        if (numa[n]>a) l1=mid1;
        else r1=mid1;
    }
    solve(r1,r2);
    printf("%.8lf",f[n]+r1*(double)a+r2*(double)b);

    return 0;
}
posted @ 2018-07-03 19:34  Maxwei_wzj  阅读(139)  评论(0编辑  收藏  举报