概率dp——逆推期望+循环迭代zoj3329
首先要推出dp[i]的期望方程,会发现每一项都和dp[0]相关,
那我们将dp[i]设为和dp[0]有关的式子dp[i]=a[i]*dp[0]+b[i],然后再回代到原来的期望方程里
然后进行整理,可以发现两个系数a[i],b[i]是可以逆推的,并且通过求出a[0],b[0]可以求出dp[0]
#include<bits/stdc++.h> using namespace std; #define maxn 1050 double A[maxn],B[maxn],p[maxn]; int main(){ double K1,K2,K3; int t,a,b,c,n; cin>>t; while(t--){ memset(p,0,sizeof p); memset(A,0,sizeof A); memset(B,0,sizeof B); cin>>n>>K1>>K2>>K3>>a>>b>>c; double base=(double)1/(K1*K2*K3); for(int i=1;i<=K1;i++) for(int j=1;j<=K2;j++) for(int k=1;k<=K3;k++) if(i==a && j==b && k==c) p[0]+=base;//跳回0的概率 else p[i+j+k]+=base;//跳i+j+k步的概率 for(int i=n;i>=0;i--){ for(int j=3;j<=K1+K2+K3;j++) A[i]+=p[j]*A[i+j],B[i]+=p[j]*B[i+j]; A[i]+=p[0],B[i]+=1; } printf("%.8lf\n",B[0]/(1-A[0])); } }