【SOJ 754】游戏

【题目】

题目描述:

AliceBob 两个人正在玩一个游戏,游戏有很多种任务,难度为 p p p 的任务( p p p 是正整数),有 1 2 p \frac{1}{2^p} 2p1 的概率完成并得到 2 p − 1 2^{p-1} 2p1 分,如果完成不了,得 0 0 0 分。一开始每人都是 0 0 0 分,从 Alice 开始轮流做任务,她可以选择任意一个任务来做;而 Bob 只会做难度为 1 1 1 的任务。只要其中有一个人达到 n n n 分,即算作那个人胜利。求 Alice 采取最优策略的情况下获胜的概率。

输入格式:

一个正整数 n n n ,含义如题目所述。

输出格式:

一个数,表示 Alice 获胜的概率,保留 6 6 6 位小数。

样例数据:

输入
1

输出
0.666667

备注:

【数据范围】
对于 30 % 30\% 30% 的数据, n n n 10 10 10
对于 100 % 100\% 100% 的数据, n n n 500 500 500


【分析】

概率 d p dp dp 入门题

定义 f i , j f_{i,j} fi,j 表示 Alice 得了 i i i 分,Bob 得了 j j j 分后 Alice 获胜的概率

那么初始化 f n , i = 1 f_{n,i}=1 fn,i=1 0 0 0 i i i n n n),最后的答案 a n s ans ans 会在 f 0 , 0 f_{0,0} f0,0

现在就考虑如何通过后面的概率来转移 f i , j f_{i,j} fi,j

我们枚举 Alice 下一步的得分(由于 Bob 只有 0 0 0 1 1 1 两种分值,不用枚举)

如果下一步的任务难度为 p p p,令 k = 2 p − 1 k=2^{p-1} k=2p1,那么拿到这 k k k 分的概率就是 1 2 p \frac{1}{2^p} 2p1(即 1 2 ⋅ k \frac{1}{2\cdot k} 2k1),不得分的概率是 2 ⋅ k − 1 2 ⋅ k \frac{2\cdot k-1}{2\cdot k} 2k2k1

那么转移方程就是: f i , j = f i + k , j 4 k + f i + k , j + 1 4 k + f i , j ⋅ ( 2 k − 1 ) 4 k + f i , j + 1 ⋅ ( 2 k − 1 ) 4 k f_{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(2k1)+4kfi,j+1(2k1)

把右边的 f i , j f_{i,j} fi,j 移到左边来的话,就是 f i , j = ( f i + k , j ) + ( f i + k , j + 1 ) + ( f i , j + 1 ⋅ ( 2 k − 1 ) ) 2 k + 1 f_{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(2k1))

应该还是比较好懂的吧


【代码】

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值