[CF739E]Gosha is hunting

2024-03-16 23:08
文章标签 hunting cf739e gosha

本文主要是介绍[CF739E]Gosha is hunting,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Gosha is hunting

题解

感觉数据范围好像开太小了,听说出题人当时给出的正解是 O ( n 2 l o g n ) O(n^2log\,n) O(n2logn)的,但我们可以用凸优化做到 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)

首先我们该如何控制两种球的使用数量分别达到 A , B A,B A,B呢,显然,dp是一种很容易想到的方法,但 O ( n 3 ) O(n^3) O(n3)的时间复杂度明显是过不了的。
考虑我们还有什么方法来控制球使用的数量。

首先,我们想到了凸优化,明显,我们用的球越多期望一定是越大的,所以如果舍掉一维去进行dp的话,他会竟可能多的选择使用这个球。
很明显,我们可以找到一个恰当的值使得每次使用这个球时期望值减去这个值后得到的最优值满足恰好有这么多个球被使用。
而这又是满足单调性的,减去的值越大,球的使用越小。
所以,我们可以去二分 B B B球的减去值,找到恰好选择 B B B个球的最优解。减去这个值的找最优解方法就是一个很简单的dp
这样,我们就可以做到 O ( n 2 l o g n ) O\left(n^2log\,n\right) O(n2logn),已经可以过题了。

但很明显,我们可以对 A A A球再进行一轮二分,二分一个减去值使得最优解恰好选择 A A A A A A球。
将两个二分套在一起后我们的dp就是一维的了,每次的时间复杂度为 O ( n ) O(n) O(n)
总时间复杂度为 O ( n l o g 2 n ) O\left(nlog^2n\right) O(nlog2n)

源码

注意精度!!!

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define MAXN 2005
#define lowbit(x) (x&-x)
#define reg register
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
const int mo=1e9+7;
const int INF=0x7f7f7f7f;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
int n,A,B;
struct ming{double val;int cnta,cntb;ming(){val=cnta=cntb=0;}ming(double V,int Ca,int Cb){val=V;cnta=Ca;cntb=Cb;}ming operator + (const ming &rhs){return ming(val+rhs.val,cnta+rhs.cnta,cntb+rhs.cntb);}
}dp[MAXN];
ming Max(ming x,ming y){return x.val<y.val?y:x;}
double p[MAXN],u[MAXN],dif1,dif2;
bool check(double k2){dif2=k2;dp[0]=ming(0,0,0); for(int i=1;i<=n;i++)dp[i]=Max(Max(dp[i-1],dp[i-1]+ming(p[i]-dif1,1,0)),Max(dp[i-1]+ming(u[i]-dif2,0,1),dp[i-1]+ming(p[i]+u[i]-p[i]*u[i]-dif1-dif2,1,1)));return dp[n].cntb>B;
}
bool sakura(double k1){dif1=k1;double l=0,r=1;int tim1=60;while(tim1--){double mid=(l+r)/2.0;if(check(mid))l=mid;else r=mid; }double mid=(l+r)/2.0;check(r);return dp[n].cnta>A;
}
signed main(){read(n);read(A);read(B);for(int i=1;i<=n;i++)scanf("%lf",&p[i]);for(int i=1;i<=n;i++)scanf("%lf",&u[i]);double l=0,r=1;int tim2=50;while(tim2--){double mid=(l+r)/2.0;if(sakura(mid))l=mid;else r=mid;}double mid=(l+r)/2.0;sakura(r);printf("%.4f\n",dp[n].val+1.0*A*dif1+1.0*B*dif2);return 0;
}

谢谢!!!

这篇关于[CF739E]Gosha is hunting的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/817030

相关文章

HDU 3468 Treasure Hunting dijkstra+网络流解决的二分匹配

题意:有最多52个点,他们分布在地图的一个地方,然后他们有先后的顺序,要按照这个顺序从第一个走到最后一个,在走每一段路的时候必须要是最短路,如果路上有金子,那么他就可以捡起一个金子,但是每一小段路只可以最多捡1个金子,问一个人从第一个点到最后一个点可以获得的最大金子数量。 想法:这是一个好题,主要考察预处理图信息的能力,代码有一点长吧。由于给的是矩阵图,我们可以把每一个点的决定信息--行列

HDU 3468 Treasure Hunting(二分匹配+最短路)

Problem Description Do you like treasure hunting? Today, with one of his friend, iSea is on a venture trip again. As most movie said, they find so many gold hiding in their trip. Now iSea’s clever

HDU 3641 Treasure Hunting

这道题貌似是10年杭州网络赛的题,乍一看挺唬人的,数据范围那么大。实际上就是个简单数论,看完题就想到解法了,只不过细节上要注意很多。 下面是详细解法: a1^b1*a2^b2*a3^b3…*an^bn ,对于这个序列,我们把每个a都质因子分解,然后整个序列中质因子的种类和个数就都知道了,然后就要求X了,对于某个X的阶乘中含有的某个质因子的个数,这个有个很简单的结论,也很好理解,log(n)时间

CF739E Gosha is hunting —— WQS二分 套 WQS二分

题目链接:点我啊╭(╯^╰)╮ 题目大意:      n n n 个神奇宝贝, a a a 个宝贝球、 b b b 个超级球     宝贝球抓到第 i i i 个神奇宝贝的概率为 p i , p_i, pi​, 超级球为 u i u_i ui​     求最大期望个数 解题思路:     很明显 n 3 n^3 n3 的 d p dp dp 很蠢     考虑到这里 恰好用 b

【CF1201】D. Treasure Hunting(dp动态规划)

题目链接:https://codeforces.com/problemset/problem/1201/D 分析 可以发现,若一行中所有的宝箱刚好都被拿完之后,只可能停在最左边或者最右边的宝箱。 那么该行的最左边的宝箱点可以从上一行的最左边或最右边的宝箱点的状态转移过来。 我们设 d p [ i ] [ 0 ] dp[i][0] dp[i][0]为刚好拿完前 i i i行宝箱后停留在第 i i