Hdu4870 Rating (Gaussian demeta or dp), hdu4870rating
RatingTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission (s): 213 Accepted Submission (s): 126
Special Judge
Problem DescriptionA little girl loves programming competition very much. recently, she has found a new kind of programming competition named "TopTopTopCoder ". every user who has registered in "TopTopTopCoder" system will have a rating, and the initial value of rating equals to zero. after the user participates in the contest held by "TopTopTopCoder", her/his rating will be updated depending on her /His rank. supposing that her/his current rating is X, if her/his rank is between on 1-200 after contest, her/his rating will be min (X + 50 ). her/His rating will be max (X-100, 0) otherwise. to reach 1000 points as soon as possible, this little girl registered two accounts. she uses the account with less rating in each contest. the possibility of her rank between on 1-200 is P for every contest . Can you tell her how her account ratings reach 1000 points?
InputThere are several test cases. Each test case is a single line containing a float number P (0.3 <= P <= 1.0). The meaning of P is described above.
OutputYou shoshould output a float number for each test case, indicating the expected count of contest she needs to participate in. This problem is special judged. The relative error less than 1e-5 will be accepted.
Sample Input
1.0000000.814700
Sample Output
39.00000082.181160
In a game, you can earn 50 points if you win the game. If you lose 100 points, the score will exceed 1000 and will not be less than 0. an individual has two accounts and is always playing with a low-score number. It is known that the probability of winning a game is the expected value of p for the number of matches that reach 1000 points.
1. Gaussian deyuan can be used,
Let E (X, Y) be the mathematical expectation that the account score is x, and y hits 1000. There are:
E (X, Y) = PE (X1, Y1) + (1-P) E (X2, Y2) + 1, X1, Y1 is the XY score, X2, y2 corresponds to the score that you lose. Suppose X> = Y. If you use the account of Y in each game, there will be 210 equations, and the index of the coefficient corresponding to the XY score will be marked with the mark array.
Code:
#include <iostream>#include <cmath>#include <stdio.h>#include <algorithm>#include <ctime>#include <vector>#include <cstring>#include <map>#include <string>#include <queue>using namespace std;#define LL long long#define ULL unsigned long long//#define REP(i,n) for(int i=0;i<n;++i)#define REP(i,a,b) for(int i=a;i<=b;++i)#define INFLL (1LL)<<62#define mset(a) memset(a,0,sizeof a)#define FR(a) freopen(a,"r",stdin)#define FW(a) freopen(a,"w",stdout)#define PI 3.141592654const LL MOD = 1000000007;const int maxn=222;const double eps=1e-9;double a[maxn][maxn];int mark[25][25];int cnt;double gauss(){ int m=211; int n=210; for(int i=0;i<n;i++) { int k=i; for(;k<n;++k) if(fabs(a[k][i])>eps) break; if(i!=k) for(int j=0;j<=n;++j) swap(a[i][j],a[k][j]); for(int j=0;j<n;++j) { if(i==j) continue; if(fabs(a[j][i])<eps) continue; double x=a[j][i]/a[i][i]; for(k=i;k<m;++k) a[j][k]-=a[i][k]*x; } } return a[0][n]/a[0][0];}void makeMat(double p){ mset(a); int m=211; int x=0,y=0; for(y=0;y<20;++y){ for(x=0;x<y;++x) { int temp=mark[y][x]; a[temp][temp]=1; a[temp][m-1]=1; int temp2=mark[y][max(0,x-2)]; a[temp][temp2]-=1-p; temp2=mark[y][x+1]; a[temp][temp2]-=p; } int t=mark[y][y]; a[t][t]=1; a[t][m-1]=1; int tt=mark[y][max(0,x-2)]; a[t][tt]-=1-p; tt=mark[x+1][x]; a[t][tt]-=p; }}int main(){ double p; cnt=0; mset(mark); REP(i,0,20) REP(j,0,i) mark[i][j]=cnt++; while (cin>>p) { makeMat(p); printf("%.6lf\n",gauss()); }}
2. Use dp
First, discretization. Because the score change in each game is a multiple of 50, each game wins 1 point and loses 2 points.
Dp [I] indicates the expected value of increasing the I score from I to I + 1 in a single game,
Dp [I] = p + (1-p) (dp [I-2] + dp [I-1] + dp [I] + 1)
=> Dp [I] = 1/p + (1-p)/p * (dp [I-2] + dp [I-1]); dp [0] = 1/p, dp [1] = 1/p;
Ans [I] [I] indicates the expectation that the scores of the two accounts will go from 0 to ii. When the scores of the two accounts increase, they will go up in different ways. This means that when their scores are the same, the previous one wins one point. After the current one wins, the next one wins, therefore, you only need to maintain ans [I + 1] [I] and ans [I + 1] [I + 1], and
Ans [I + 1] [I] = ans [I] [I] + dp [I], ans [I + 1] [I + 1] = ans [I + 1] [I] + dp [I],
Code:
#include <iostream>#include <cmath>#include <stdio.h>using namespace std;double dp[22];double ans[22][22];int main(){ double p; while (cin>>p) { dp[0]=1/p; dp[1]=1/p/p; for(int i=2;i<20;++i) dp[i] = 1+(1-p)/p*(dp[i-2]+dp[i-1]+1); ans[0][0]=0; for (int i=0;i<20;++i) { ans[i+1][i]=ans[i][i]+dp[i]; ans[i+1][i+1]=ans[i+1][i]+dp[i]; } printf("%.6lf\n",ans[20][19]); }}