网站如何做标题优化/国外网站加速
【题目】
题目描述:
Alice 和 Bob 两个人正在玩一个游戏,游戏有很多种任务,难度为 ppp 的任务(ppp 是正整数),有 12p\frac{1}{2^p}2p1 的概率完成并得到 2p−12^{p-1}2p−1 分,如果完成不了,得 000 分。一开始每人都是 000 分,从 Alice 开始轮流做任务,她可以选择任意一个任务来做;而 Bob 只会做难度为 111 的任务。只要其中有一个人达到 nnn 分,即算作那个人胜利。求 Alice 采取最优策略的情况下获胜的概率。
输入格式:
一个正整数 nnn ,含义如题目所述。
输出格式:
一个数,表示 Alice 获胜的概率,保留 666 位小数。
样例数据:
输入
1
输出
0.666667
备注:
【数据范围】
对于 30%30\%30% 的数据,nnn ≤ 101010
对于 100%100\%100% 的数据,nnn ≤ 500500500
【分析】
概率 dpdpdp 入门题
定义 fi,jf_{i,j}fi,j 表示 Alice 得了 iii 分,Bob 得了 jjj 分后 Alice 获胜的概率
那么初始化 fn,i=1f_{n,i}=1fn,i=1(000 ≤ iii ≤ nnn),最后的答案 ansansans 会在 f0,0f_{0,0}f0,0 中
现在就考虑如何通过后面的概率来转移 fi,jf_{i,j}fi,j
我们枚举 Alice 下一步的得分(由于 Bob 只有 000 和 111 两种分值,不用枚举)
如果下一步的任务难度为 ppp,令 k=2p−1k=2^{p-1}k=2p−1,那么拿到这 kkk 分的概率就是 12p\frac{1}{2^p}2p1(即 12⋅k\frac{1}{2\cdot k}2⋅k1),不得分的概率是 2⋅k−12⋅k\frac{2\cdot k-1}{2\cdot k}2⋅k2⋅k−1
那么转移方程就是:fi,j=fi+k,j4k+fi+k,j+14k+fi,j⋅(2k−1)4k+fi,j+1⋅(2k−1)4kf_{i,j}=\frac{f_{i+k,j}}{4k}+\frac{f_{i+k,j+1}}{4k}+\frac{f_{i,j}\cdot(2k-1)}{4k}+\frac{f_{i,j+1}\cdot (2k-1)}{4k}fi,j=4kfi+k,j+4kfi+k,j+1+4kfi,j⋅(2k−1)+4kfi,j+1⋅(2k−1)
把右边的 fi,jf_{i,j}fi,j 移到左边来的话,就是 fi,j=(fi+k,j)+(fi+k,j+1)+(fi,j+1⋅(2k−1))2k+1f_{i,j}=\frac{(f_{i+k,j})+(f_{i+k,j+1})+({f_{i,j+1}\cdot (2k-1)})}{2k+1}fi,j=2k+1(fi+k,j)+(fi+k,j+1)+(fi,j+1⋅(2k−1))
应该还是比较好懂的吧
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 505
using namespace std;
double f[N][N];
int main()
{int n,i,j,k;scanf("%d",&n);for(i=0;i<=n;++i)f[n][i]=1;for(i=n-1;i>=0;--i)for(j=n-1;j>=0;--j)for(k=1;k/2<=n;k<<=1){int next=min(i+k,n);f[i][j]=max(f[i][j],(f[next][j]+f[next][j+1]+f[i][j+1]*(2*k-1))/(2.0*k+1.0));}printf("%.6lf",f[0][0]);return 0;
}