标签:std ons style ... const main tco highlight min
题意:两个人玩游戏,A在$1\cdots n$中随机选一个数,B来猜数,B每次可以询问一个数,而A会告诉B他猜大了还是猜小了,B不允许做出无用询问,问B猜测次数$\in[a,b]$的概率是多少(B希望猜测次数$\in[a,b]$并采取了最优策略)
B会提前制定策略:第一轮猜$x$,如果答案$\lt x$或$\gt x$那么接下来有对应的策略,如果猜中了就结束,把游戏的所有可能画出来,它形成了一棵二叉搜索树,我们的目标即是最大化深度$\in[a,b]$的节点个数
考虑枚举深度为$a$的节点有$x$个,那么需要的祖先节点容易$O(\log n)$递归计算,再将剩下的节点贪心地填在深度为$[a+1,b]$的点即可
这个题,转成二叉树这一步还是挺妙的吧...
#include<stdio.h> #include<algorithm> using namespace std; typedef double du; const int inf=2147483647; int f(int a,int x){ if(x==1)return a; if(a==1)return inf; int t=f(a-1,(x+1)/2); if(t==inf)return inf; return x+t; } class WellTimedSearch{ public: du getProbability(int n,int a,int b){ int i,j,t,mx,s,c; mx=0; for(i=1;i<=n;i++){ t=f(a,i); if(t>n)break; t=n-t; s=i; c=i; for(j=a+1;t&&j<=b;j++){ c*=2; s+=min(c,t); t-=min(c,t); } mx=max(mx,s); } return mx/(du)n; } }; /* int main(){ int n,a,b; WellTimedSearch cl; scanf("%d%d%d",&n,&a,&b); printf("%.11lf",cl.getProbability(n,a,b)); } */
标签:std ons style ... const main tco highlight min
原文地址:https://www.cnblogs.com/jefflyy/p/9748306.html