【CF739E】Gosha is hunting(WQS二分套WQS二分)

点此看题面

大致题意: 你有两种捕捉球(分别为\(A\)个和\(B\)个),要捕捉\(n\)个神奇宝贝,第\(i\)个神奇宝贝被第一种球捕捉的概率是\(s1_i\),被第二种球捕捉的概率是\(s2_i\),问在最优策略下期望捕捉到的神奇宝贝数量。


\(WQS\)二分

这应该是一道比较经典的\(WQS\)二分题(毕竟是 \(WQS\)二分套\(WQS\)二分)。


\(WQS\)二分套\(WQS\)二分

如果你知道\(WQS\)二分,应该就不难想到\(WQS\)二分一个代价\(C1\),表示每使用一个第一种球所需要的代价,然后再\(WQS\)二分一个代价\(C2\),表示每使用一个第二种球所需要的代价。于是就成了\(WQS\)二分套\(WQS\)二分。


\(DP\)转移

在\(WQS\)二分后,就是\(DP\)了。

我们可以用\(f_i\)表示到第\(i\)个神奇宝贝为止捕捉到的神奇宝贝总数的最大期望值,并用\(g1_i\)表示此时使用的第一种捕捉球个数,用\(g2_i\)表示此时使用的第二种捕捉球个数

其实\(DP\)也是挺简单的,共有\(4\)种情况:

  • 不使用捕捉球。\(f_i=f_{i-1},g1_i=g1_{i-1},g2_i=g2_{i-1}\)。
  • 使用第一种捕捉球。\(f_i=f_{i-1}+s1_i-C1,g1_i=g1_{i-1}+1,g2_i=g2_{i-1}\)
  • 使用第二种捕捉球。\(f_i=f_{i-1}+s2_i-C2,g1_i=g1_{i-1},g2_i=g2_{i-1}+1\)
  • 同时使用两种捕捉球。\(f_i=f_{i-1}+s1_i+s2_i-C1-C2-s1_i*s2_i,g1_i=g1_{i-1}+1,g2_i=g2_{i-1}+1\)

这样就可以了。


代码

#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e9
#define Inc(x,y) ((x+=(y))>=MOD&&(x-=MOD))
#define ten(x) (((x)<<3)+((x)<<1))
#define N 100000
#define eps 1e-12
using namespace std;
int n,A,B;double s1[N+5],s2[N+5];
class Class_WQS//WQS二分套WQS二分
{
    private:
        double C1,C2,f[N+5];int g1[N+5],g2[N+5];//用f[i]表示到第i个神奇宝贝为止捕捉到的神奇宝贝总数的最大期望值,并用g1[i]表示此时使用的第一种捕捉球个数,用g2[i]表示此时使用的第二种捕捉球个数
        inline void check()//DP转移
        {
            for(register int i=1;i<=n;++i)
            {
                f[i]=f[i-1],g1[i]=g1[i-1],g2[i]=g2[i-1];//不使用捕捉球
                if(f[i-1]+(s1[i]-C1)-f[i]>eps) f[i]=f[i-1]+(s1[i]-C1),g1[i]=g1[i-1]+1,g2[i]=g2[i-1];//使用第一种捕捉球
                if(f[i-1]+(s2[i]-C2)-f[i]>eps) f[i]=f[i-1]+(s2[i]-C2),g1[i]=g1[i-1],g2[i]=g2[i-1]+1;//使用第二种捕捉球
                if(f[i-1]+(s1[i]+s2[i]-C1-C2-s1[i]*s2[i])-f[i]>eps) f[i]=f[i-1]+(s1[i]+s2[i]-C1-C2-s1[i]*s2[i]),g1[i]=g1[i-1]+1,g2[i]=g2[i-1]+1;//同时使用两种捕捉球
            }
        }
        inline void GetRes()//第二层二分,二分C2
        {
            register double l=0.0,r=1.0;
            for(C2=(l+r)/2;r-l>eps;C2=(l+r)/2)
            {
                if(check(),!(g2[n]^B)) return;//找到符合条件的C2,就可以return了
                g2[n]>B?l=C2:r=C2;//如果选得物品数量偏多,将l更新为C2,否则将r更新为C2
            }
        }
    public:
        inline double GetAns()//第一层二分,二分C1
        {
            register double l=0.0,r=1.0;
            for(C1=(l+r)/2;r-l>eps;C1=(l+r)/2)
            {
                if(GetRes(),!(g1[n]^A)) break;//找到符合条件的C1,就可以break了
                g1[n]>A?l=C1:r=C1;//如果选得物品数量偏多,将l更新为C1,否则将r更新为C1
            }
            return f[n]+A*C1+B*C2;//返回答案
        }
}WQS;
int main()
{
    register int i;
    scanf("%d%d%d",&n,&A,&B);
    for(i=1;i<=n;++i) scanf("%lf",&s1[i]);
    for(i=1;i<=n;++i) scanf("%lf",&s2[i]);
    return printf("%.10lf\n",WQS.GetAns()),0;
}

原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF739E.html

时间: 2024-07-30 11:31:09

【CF739E】Gosha is hunting(WQS二分套WQS二分)的相关文章

CF739E Gosha is hunting DP+wqs二分

我是从其他博客里看到这题的,上面说做法是wqs二分套wqs二分?但是我好懒呀,只用了一个wqs二分,于是\(O(nlog^2n)\)→\(O(n^2logn)\) 首先我们有一个\(O(n^3)\)的暴力\(DP\),转移好写,形式优美,但复杂度不对 该怎样发现它的凸性质呢 1.打表√ 2.冷静分析一波,每一种球肯定是越多越好,于是我们先固定选择\(a\)个普通球,然后那\(b\)个大师球肯定是从大到小挑选.这样的话每多选一个,新增的收益就会下降一点,也就是说这是个上凸函数.(口胡如果假的话,就

cf739E Gosha is hunting (flows)

739E 有$a$个普通球,$b$个超级球,有$n$个要捕捉的宝可梦,对于第$i$个宝可梦普通球的捕捉概率是$p_i$,超级球的捕捉概率是$u_i$,每种球只能扔一个到同一个宝可梦,同一个宝可梦可以被扔两种球.然后问在最优策略下捕捉个数的期望 考虑概率$dp$,发现状态无法简化到$n^2$级别,原来不是dp 假定每个宝可梦只能被扔一个球,那就是个匹配问题了,设$A$为普通球,$B$为超级球,源点向$A$,$B$连容量为球的个数,花费为$0$的边,$A,B$分别向每个精灵连容量为$1$,花费为$p

CF739E Gosha is hunting 【WQS二分 + 期望】

题目链接 CF739E 题解 抓住个数的期望即为概率之和 使用\(A\)的期望为\(p[i]\) 使用\(B\)的期望为\(u[i]\) 都使用的期望为\(p[i] + u[i] - u[i]p[i]\) 当然是用越多越好 但是他很烦地给了个上限,我们就需要作出选择了 有一个很明显的\(O(n^3)\)的\(dp\),显然过不了 但我们有一个很好的\(WQS\)二分 我们非常想去掉这个上限 那就去掉吧,但是每用一次都要付出一个代价 我们二分这个代价,当使用次数恰好为为\(a\)和\(b\)时就是

CF739E Gosha is hunting

法一: 匹配问题,网络流! 最大费用最大流,S到A,B流a/b费0,A,B到i流1费p[i]/u[i],同时选择再减p[i]*u[i]? 连二次!所以i到T流1费0流1费-p[i]*u[i] 最大流由于ab都选择完最优 最大费用,所以不会第一次走-p[i]*u[i] 法二: DP怎么写? dp[i][j][k] 优化? 一定选择a.b个! 恰好选择a.b个? WQS二分! 一定是满足凸函数的性质的 所以选择若干个a,代价ca,求dp[i][b] 再次WQS二分! 所以选择若干个a,b,代价ca,

CF739E Gosha is hunting(费用流,期望)

根据期望的线性性答案就是捕捉每一只精灵的概率之和. 捕捉一只精灵的方案如下: 1.使用一个\(A\)精灵球,贡献为\(A[i]\) 2.使用一个\(B\)精灵球,贡献为\(B[i]\) 3.使用一个\(A\)精灵球和一个\(B\)精灵球,贡献为\(A[i]+B[i]-A[i]*B[i]\) 然后我们可以这样建图: 源点\(S\)向两个精灵球连容量为精灵球数量,费用为\(0\)的边. \(A\)精灵球向i连容量为\(1\),费用为\(A[i]\)的边. \(B\)精灵球向i连容量为\(1\),费用

Codeforces.739E.Gosha is hunting(DP 带权二分)

题目链接 \(Description\) 有n只精灵,两种精灵球,每种球能捕捉到第i只精灵的概率已知.求用A个低级球和B个高级球能捕捉到精灵数的最大期望. \(Solution\) 设f[i][a][b]表示前i只用了a个低级球,b个高级球的最大期望.转移时四种情况显然.复杂度\(\mathcal O(nAB)\). 随着某种球可使用数的增多,f应是凸函数,即增长越来越慢.而且两种球都满足这个性质. 于是可以wqs二分套wqs二分了..没有个数限制取个max记一下个数就可以了.复杂度\(\mat

【CF739E】Gosha is hunting 贪心

[CF739E]Gosha is hunting 题意:有n个小精灵,你有a个普通球和b个超级球,用普通球抓住第i只小精灵的概率为$A_i$,用超级球抓住第i只小精灵的概率为$u_i$.你必须一开始就决定向哪些精灵投掷哪些精灵球,同种的球只能对一个精灵用一次,可以对一只精灵投掷两种球,如果两次中有一次抓到则视为抓到.问你如果采用最优的方案,最终抓到小精灵的期望个数是多少. $n\le 2000$. 题解:我们先将所有小精灵按$B$排序,然后我们枚举最后一个投b或ab的小精灵i,那么不难证明i左边

POJ 3685 二分套二分

Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix. Input The first line of input is the number of test

【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

第一种做法(时间太感人): 这题我真的逗了,调了一下午,疯狂造数据,始终找不到错. 后来发现自己sb了,更新那里没有打id,直接套上u了.我.... 调了一下午啊!一下午的时光啊!本来说好中午A掉去学习第二种做法,噗 好吧,现在第一种做法是hld+seg+bst+二分,常数巨大,log^4级别,目前只会这种. 树剖后仍然用线段树维护dfs序区间,然后在每个区间建一颗平衡树,我用treap,(这题找最大啊,,,囧,并且要注意,这里的rank是比他大的数量,so,我们在二分时判断要判断一个范围,即要