暂无链接
炉石
题目描述
shy 很喜欢玩炉石传说天梯模式,天梯模式规则是这样的。
首先有 25 个等级,最低 25 级,最高 1 级。你需要和别人进行天梯比赛来获得更多的星。
如果你胜利了,你会获得一颗星,如果你失败了,你会失去一颗星。当你当前的星大于一个指定的数目的时候,你将升入下一等级(即等级减一),并且扣除这个数目的星,这个数目与当前等级有关。其中 25 到 21 级需要 2 个星升级。20 到 16 需要 3 个。15 到 10 需要 4 个。10 到 1 需要 5 个。特别的,如果在 1 级 5 星获胜,你将成为传说。当你当前为 0 星的时候,并且失去一颗星,你会退回到上一等级(即等级加一),并且获得升级所需要的星,然后失去那一颗星。当你当前的状态是 20 级 0 星或更低时,你的失败不会导致星的损失。当你这局比赛和之前两局比赛均胜利时,且当前的等级不在 1 到 5 级之间时,你可以获得连胜奖励,额外的一颗星,这颗星对升级的影响和一般胜利的星一样。
shy 打算从一共 x 星开始玩,shy 每一局的胜率是 p。他想知道自己期望上传说需要多少盘天梯比赛。
输入说明
第一行第一个整数 n 表示差多少颗星到传说,第二个实数,表示胜率 p。
输出说明
一行一个实数表示答案。(保留两位小数)
样例输入
96 0.5
样例输出
1384.70
数据规模
对于 10%的数据,0≤n≤96,p=1;
对于 100%的数据,0≤n≤96,0.48≤p≤1;
题解
当然是得完10分走人啊。
拿到题首先可以想到 dp d p 做法,用 dp[i][j] d p [ i ] [ j ] 表示获得 i i 颗星同时连胜场这个状态出现的概率,但是这个转移显然是有环的,所以各位大佬就想到了高斯消元。
不过我向来喜欢正确性不高的做法(滑稽)。
代码
#include<bits/stdc++.h>
using namespace std;
const int M=100;
double win,los,ans,tmp[M][4],pre[M][4];int n;
void in(){scanf("%d%lf",&n,&win);}
void ac()
{
los=1-win,pre[96-n][0]=1;
for(int k=1;k<=22500;++k)
{
for(int i=0;i<=10;++i)tmp[i][0]+=pre[i][0]*los,tmp[i][0]+=pre[i][1]*los,tmp[i][0]+=pre[i][2]*los,tmp[i+1][1]+=pre[i][0]*win,tmp[i+1][2]+=pre[i][1]*win,tmp[i+2][2]+=pre[i][2]*win;
for(int i=11;i<=70;++i)tmp[i-1][0]+=pre[i][0]*los,tmp[i-1][0]+=pre[i][1]*los,tmp[i-1][0]+=pre[i][2]*los,tmp[i+1][1]+=pre[i][0]*win,tmp[i+1][2]+=pre[i][1]*win,tmp[i+2][2]+=pre[i][2]*win;
for(int i=71;i<=95;++i)tmp[i-1][0]+=pre[i][0]*los,tmp[i-1][0]+=pre[i][1]*los,tmp[i-1][0]+=pre[i][2]*los,tmp[i+1][1]+=pre[i][0]*win,tmp[i+1][2]+=pre[i][1]*win,tmp[i+1][2]+=pre[i][2]*win;
ans+=(tmp[96][0]+tmp[96][1]+tmp[96][2])*k;memcpy(pre,tmp,sizeof(tmp));memset(tmp,0,sizeof(tmp));
}
printf("%.2lf",ans);
}
int main(){in();ac();}