比赛时没写出来导致没拿到银,自闭。
一开始想到概率dp,但是没想到初始状态,就去推公式了,(思维僵化)。
以 q 为 dp 数组下标,当 q 为100%时,期望步数为 1/p。把这个期望作为初始状态往下逆推。(这里要是想出来应该就好写了)
因为还没有交题平台,所以也不能说自己写的是对的。。。 大体思路应该是对的吧,毕竟样例过了就是过了(滑稽脸)
据说还有随机100w次过的(发抖) 我用伪随机算法试了下,精度只有小数点后三位(写丑了?还是太菜。。。。)
#include<bits/stdc++.h>
#define ll long long
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
double dp[1001]; //下标为q*1000
double eps=1e-8;
int main()
{
ios::sync_with_stdio(0);
int T;
cin>>T;
while(T--)
{
double p;
cin>>p;
p=p/100;
mem(dp,0);
dp[1000]=1/p;
for(int i=1000;i>=20;i--)
{
if(i+20<=1000&&dp[i+20]>0)
{
dp[i]=i/1000.0*p*1.0+p*(1-i/1000.0)*(dp[i+20]+1);
}
if(i+15<=1000&&dp[i+15]>0)
{
if(dp[i]>eps)
dp[i]+=(1-p)*(dp[i+15]+1);
else if(p<1.0-eps)
dp[i]=i/1000.0*p*1.0+(1-p)*(dp[i+15]+1);
}
}
cout<<fixed<<setprecision(10)<<dp[20]<<endl;
}
return 0;
}