[CF739E Gosha is hunting]带权二分
时间根本不会给我任何答案,明明已经一年了,再次看见依然是那么痛苦.
以下是刚学的带权二分:
网络流做法在此不赘述
本来有一个n^3的dp,f[i][j][k]前i个p打了j,u打了k.
由于始终满足炮打得越多越好,所以如果我们利用带权二分限制打了多少个p,第一层二分限制打p,第二层二分限制打u,即在原本打p或u可以得到的价值减去二分的值,使得恰好达到a个p,b个u.对于精度二分,我们二分一个固定次数就可以了.
题意翻译
你要抓神奇宝贝! 现在一共有 N 只神奇宝贝。 你有 a 个『宝贝球』和 b 个『超级球』。 『宝贝球』抓到第 i 只神奇宝贝的概率是 p_i ,『超级球』抓到的概率则是 u_i 。 不能往同一只神奇宝贝上使用超过一个同种的『球』,但是可以往同一只上既使用『宝贝球』又使用『超级球』(都抓到算一个)。 请合理分配每个球抓谁,使得你抓到神奇宝贝的总个数期望最大,并输出这个值。 Translated by @zhoutb2333题目描述
Gosha is hunting. His goal is to catch as many Pokemons as possible. Gosha has a Poke Balls and b Ultra Balls. There are n Pokemons. They are numbered 1 through n . Gosha knows that if he throws a Poke Ball at the i -th Pokemon he catches it with probability p_{i} . If he throws an Ultra Ball at the i-th Pokemon he catches it with probability u_{i} . He can throw at most one Ball of each type at any Pokemon. The hunting proceeds as follows: at first, Gosha chooses no more than aPokemons at which he will throw Poke Balls and no more than b Pokemons at which he will throw Ultra Balls. After that, he throws the chosen Balls at the chosen Pokemons. If he throws both Ultra Ball and Poke Ball at some Pokemon, he is caught if and only if he is caught by any of these Balls. The outcome of a throw doesn't depend on the other throws. Gosha would like to know what is the expected number of the Pokemons he catches if he acts in an optimal way. In other words, he would like to know the maximum possible expected number of Pokemons can catch.输入输出格式
输入格式: The first line contains three integers n , a and b ( 2<=n<=2000 , 0<=a,b<=n ) — the number of Pokemons, the number of Poke Balls and the number of Ultra Balls. The second line contains n real values p_{1},p_{2},...,p_{n} ( 0<=p_{i}<=1 ), where p_{i} is the probability of catching the i -th Pokemon if Gosha throws a Poke Ball to it. The third line contains n real values u_{1},u_{2},...,u_{n} ( 0<=u_{i}<=1 ), where u_{i} is the probability of catching the i -th Pokemon if Gosha throws an Ultra Ball to it. All the probabilities are given with exactly three digits after the decimal separator. 输出格式: Print the maximum possible expected number of Pokemons Gosha can catch. The answer is considered correct if it's absolute or relative error doesn't exceed 10^{-4} .输入输出样例
#include<stdio.h> #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> typedef double db; const db eps = 1e-10; using namespace std; int n,a,b; db p[2005],u[2005]; int nma[2005],nmb[2005]; db f[2005]; void ck(db ca,db cb) { for(int i=1;i<=n;i++) { f[i] = f[i-1]; nma[i] = nma[i-1]; nmb[i] = nmb[i-1]; if(f[i] + eps < f[i-1] + p[i] - ca ) { f[i] = f[i-1] + p[i] - ca; nma[i] = nma[i-1] + 1; nmb[i] = nmb[i-1]; } if(f[i] + eps < f[i-1] + u[i] - cb ) { f[i] = f[i-1] + u[i] - cb; nma[i] = nma[i-1]; nmb[i] = nmb[i-1] + 1; } if(f[i] + eps < f[i-1] + p[i] + u[i] - p[i]*u[i] - ca - cb) { f[i] = f[i-1] + p[i] + u[i] - p[i]*u[i] - ca - cb; nma[i] = nma[i-1] + 1; nmb[i] = nmb[i-1] + 1; } } } db chea(db ca) { db l = 0; db r = 1 , mid; for(int i=1;i<=50;i++) { mid = (l+r)*0.5; ck(ca,mid); if(nmb[n]>b) l = mid; else r = mid; } return mid; } 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",&u[i]); } db l = 0; db r = 1,mid,vv; for(int i=1;i<=50;i++) { mid = (l+r)*0.5; vv = chea(mid); if(nma[n]>a) l = mid; else r = mid; } ck(mid,vv); printf("%.6lf",f[n] + mid*a + vv*b ); }