dp[i][j]表示两个号的分数为i,j时,到达目标的期望,规定i<=j;
题可变为min(x+1,20),max(x-2,0).,,要求dp[0][0];
对于高分j为5时,可列方程:(q==(1-p))
dp[0][5]=p*dp[1][5] + q*dp[0][5] + 1;
dp[1][5]=p*dp[2][5] + q*dp[0][5] + 1;
dp[2][5]=p*dp[3][5] + q*dp[0][5] + 1;
dp[3][5]=p*dp[4][5] + q*dp[1][5] + 1;
dp[4][5]=p*dp[5][5] + q*dp[2][5] + 1;
dp[5][5]=p*dp[5][6] + q*dp[3][5] + 1;
化简得:
dp[1][5]=(1/p)*dp[0][5] - (q/p)*dp[0][5] - (1/p);
dp[2][5]=(1/p)*dp[1][5] - (q/p)*dp[0][5] - (1/p);
dp[3][5]=(1/p)*dp[2][5] - (q/p)*dp[0][5] - (1/p);
dp[4][5]=(1/p)*dp[3][5] - (q/p)*dp[1][5] - (1/p);
dp[5][5]=(1/p)*dp[4][5] - (q/p)*dp[2][5] - (1/p);
dp[5][6]=(1/p)*dp[5][5] - (q/p)*dp[3][5] - (1/p);
设dp[i][j] = a[i]*dp[0][j] + b[i];
a[0]=1,b[0]=0; (dp[0][j] = dp[0][j])
由上化简式得:a[i]=(1/p)*a[i-1] - (q/p)*a[max(i-3,0)];
b[i]=(1/p)*b[i-1] - (q/p)*b[max(i-3,0)] - (1/p);
……
dp[5][5]=a[5]*dp[0][5] + b[5];
dp[5][6]=a[6]*dp[0][5] + b[6];
有上式得:dp[j][j+1] = a[j+1]*dp[0][j] + b[j+1];
已知:dp[19][20]=0;
可求得:dp[0][19],
可求得:dp[18][19],
可求得:dp[0][18],
……
可求得:dp[0][1],
可求得:dp[0][0],
即不需要dp数组,求出系数a[i]、b[i].即可导出dp[0][0];
实现代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define ll long long
double a[22],b[22];
int main()
{
double p;
while(scanf("%lf",&p)!=EOF)
{
a[0]=1,b[0]=0;
double p1=1.0/p;
double p2=(1.0-p)/p;
int i,j,k;
for(i=1;i<=20;i++)
{
a[i]=p1*a[i-1]-p2*a[max(i-3,0)];
b[i]=p1*b[i-1]-p2*b[max(i-3,0)]-p1;
}
double ans=0;
for(j=19;j>=1;j--)
{
ans=(ans-b[j+1])/a[j+1];
ans=a[j-1]*ans+b[j-1];
}
ans=(ans-b[1])/a[1];
printf("%.8lf\n",ans);
}
}