题意 :小女孩注册了两个比赛的帐号,初始分值都为0,每做一次比赛如果排名在前两百名,rating涨50,否则降100,告诉你她每次比赛在前两百名的概率p,如果她每次做题都用两个账号中分数低的那个去做,问她最终有一个账号达到1000分需要做的比赛的次数的期望值。
思路 :可以直接用公式推出来用DP做,也可以列出210个方程组用高斯消元去做。
(1)DP1:离散化。因为50,100,1000都是50的倍数,所以就看作1,2,20。这样做起来比较方便。
定义dp[i]为从 i 分数到达i+1分的期望,状态转移方程:
dp[i] = p+(1-p)*(1+dp[i-2]+dp[i-1]+dp[i]); 在前两百名里增加一分,当不在前两百名里的时候,扣两分,要回到 i+1 分就是1+dp[i-2]+dp[i-1]+dp[i].
mp[i][i]表示两个账号都从0分涨到 i 分的期望,所以mp[i+1][i] = mp[i][i]+dp[i], mp[i+1][i+1] = mp[i+1][i]+dp[i];
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <math.h> 5 6 using namespace std ; 7 8 double dp[21],mp[21][21] ; 9 10 int main() 11 { 12 double p ; 13 while(scanf("%lf",&p) != EOF) 14 { 15 dp[0] = 1 / p ; 16 dp[1] = 1 / p / p ; 17 for(int i = 2 ; i < 20 ; i++) 18 dp[i] = 1 + (1-p)*(dp[i-2]+dp[i-1]+1)/p ; 19 for(int i = 0 ; i < 20 ; i++) 20 { 21 mp[i+1][i] = mp[i][i]+dp[i] ; 22 mp[i+1][i+1] = mp[i+1][i] + dp[i] ; 23 } 24 printf("%.6lf\n",mp[20][19]) ; 25 } 26 return 0 ; 27 }