hdu 4870 Rating (概率dp)

来源:互联网 发布:穆雅斓的淘宝店斌斌 编辑:程序博客网 时间:2024/05/20 06:29

题意:

给出一个人升级的流程,对于每次操作如果rank在1-200那么rating会涨min(x+50,1000),否则ranting会涨(x-100,0)相当于减rating。rank在1-200的范围的概率是p。

求rating达到1000操作数的期望。

题解在注释里。其实可以离散化,将x+50,1000,x-100,0离散化,就是x+1,20,x-2,0;

/**对于单个账号的期望E[i]表示打到i分段的期望令q=1-p;E[i]=E[i+1]*p+E[i-2]*q;显然这个没办法用递推,因为E[i+1]没计算出来。这个暂且不提。我们分析下两个账号的情况在递推是肯定有这样:(0,0)->(0,1) (0,0)->(1,0) (1,0)->(2,0)....等对于其中的(0,0)->(1,0)结果是E[1]-E[0],其他同理。那么总的期望可以是这些差的和?猜测!将所有罗列出来,发现和的答案会累赘就是说因为最后一步时(19,19)->(20,19)或者(19,19)->(19,20)这两者其中一个发生就可以了,那么用之前的和减去E[20]-E[19];那么我们令dp[i]=E[i+1]-E[i];于是dp[i]=(dp[i-1]-dp[i-3]*q)/p;结果为sum-dp[19];*/#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))void cmax(int& a,int b){ if(b>a)a=b; }void cmin(int& a,int b){ if(b<a)a=b; }typedef unsigned long long ll;const int oo=0x3f3f3f3f;const int MOD=1000000007;const int maxn=22;double dp[maxn];double DP(double p){    memset(dp,0,sizeof dp);    double sum=0;    dp[0]=1/p;dp[1]=dp[0]/p;dp[2]=dp[1]/p;    sum=dp[0]+dp[1]+dp[2];    for(int i=3;i<20;i++){        dp[i]=(dp[i-1]-dp[i-3]*(1.0-p))/p;        sum+=dp[i];    }    return sum*2-dp[19];}int main(){    double p;    while(scanf("%lf",&p)!=EOF){        printf("%.6lf\n",DP(p));    }return 0;}



0 0
原创粉丝点击