poj 2096 Collecting Bugs 概率DP
思路:仔细读懂题意。
dp[i][j]表示第i个bug,第j个子系统;那么状态转移就有4种可能:
dp[i][j],概率是p1=i/n*j/s;
dp[i+1][j],概率是p2=(n-i)/n*j/s;
dp[i][j+1],概率是p3=i/n*(s-j)/s;
dp[i+1][j+1],概率是p4=(n-i)/n*(s-j)/s;
那么就有:
dp[i][j]=p1*(dp[i][j]+1)+p2*(dp[i+1][j]+1)+p3*(dp[i][j+1]+1)+p4*(dp[i+1][j+1]+1) //注意这里加1是因为本次操作花费一天
=p1*dp[i][j]+p2*dp[i+1][j]+p3*dp[i][j+1]+p4*dp[i+1][j+1]+1
整理的:
dp[i][j]=(n*s+(n-i)*j*dp[i+1][j]+i*(s-j)*dp[i][j+1]+(n-i)*(s-j)*dp[i+1][j+1])/(n*s-i*j)
代码如下:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iomanip> 5 #include<cmath> 6 #include<string> 7 #include<vector> 8 #define ll __int64 9 #define pi acos(-1.0) 10 #define MAX 1005 11 using namespace std; 12 double dp[MAX][MAX]; 13 int main(){ 14 int n,i,j,s; 15 cin>>n>>s; 16 dp[n][s]=0.0; 17 for(i=n;i>=0;i--) 18 for(j=s;j>=0;j--){ 19 if(i==n&&j==s) continue; 20 dp[i][j]=(n*s+i*(s-j)*dp[i][j+1]+(n-i)*j*dp[i+1][j]+(n-i)*(s-j)*dp[i+1][j+1])/(n*s-i*j); 21 } 22 printf("%.4lf\n",dp[0][0]); 23 return 0; 24 }