HDU 4089 Activation 概率DP
解题报告链接:
http://www.cnblogs.com/183zyz/archive/2012/09/13/2683524.html
另一份解题报告:
http://www.cnblogs.com/kuangbin/archive/2012/10/03/2710987.html
先自己推出递推式···再化简,然后解不等式即可···这个式子比较有特点,所以好解。
x = ax+b。
关键是求出系数a和b````
我用c1记录x的临时系数,c0记录常数
最后求得d[i][i] = c0/(1-c1);
然后顺着推出c[i][1] --- c[i][i-1]````
还有要注意当p4很小时,直接输出0.00000,否则去计算的话,会出现误差,使得结果不为0
贴代码:
1 #include <cstdio> 2 #define N 2005 3 #define eps 1e-10 4 double dp[N][N]; 5 int main() 6 { 7 // freopen("in.c","r",stdin); 8 int n,m,k; 9 double p1,p2,p3,p4,q2,q3,q4; 10 while(~scanf("%d %d %d %lf %lf %lf %lf",&n,&m,&k,&p1,&p2,&p3,&p4)) 11 { 12 if(p4 < eps) 13 { 14 printf("0.00000\n"); 15 continue; 16 } 17 q2 = p2/(1-p1); 18 q3 = p3/(1-p1); 19 q4 = p4/(1-p1); 20 double c1,c0; 21 dp[1][1] = p4/(1-p1-p2); 22 for(int i=2; i<=n; ++i) 23 { 24 c1 = q2; 25 c0 = q4; 26 for(int j = 2; j<=i && j<=k; ++j) 27 { 28 c1 *= q2; 29 c0 = c0*q2+q3*dp[i-1][j-1]+q4; 30 } 31 for(int j=k+1; j<=i; ++j) 32 { 33 c1 *= q2; 34 c0 = c0*q2 + q3*dp[i-1][j-1]; 35 } 36 dp[i][i] = c0/(1-c1); 37 dp[i][1] = q2*dp[i][i]+q4; 38 for(int j=2; j<=i && j<=k; ++j) 39 dp[i][j] = q2*dp[i][j-1] + q3*dp[i-1][j-1]+q4; 40 for(int j=k+1; j<i; ++j) 41 dp[i][j] = q2*dp[i][j-1] + q3*dp[i-1][j-1]; 42 } 43 printf("%.5f\n",dp[n][m]); 44 } 45 return 0; 46 }