概率DP:
1.期望可以分解成多个子期望的加权和,权为子期望发生的概率,即 E(aA+bB+…) = aE(A) + bE(B) +…+1;
2.期望从后往前找,一般dp[n]=0,dp[0]是答案;
3.解决过程,找出各种情况乘上这种情况发生的概率,求和;
#include<iostream> #include<cstdio> #define rep(i, n) for(int i=0;i!=n;++i) #define per(i, n) for(int i=n-1;i>=0;--i) #define Rep(i, sta, n) for(int i=sta;i!=n;++i) #define rep1(i, n) for(int i=1;i<=n;++i) #define per1(i, n) for(int i=n;i>=1;--i) #define Rep1(i, sta, n) for(int i=sta;i<=n;++i) #define L k<<1 #define R k<<1|1 #define inf (0x3f3f3f3f) #define llinf (1e18) #define mid (tree[k].l+tree[k].r)>>1 #define ALL(A) A.begin(),A.end() #define SIZE(A) ((int)A.size()) typedef long long i64; using namespace std; const int maxn = 1024; double dp[maxn][maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,s; cin>>n>>s; dp[n][s] = 0; for(int i=n;i>=0;--i) for(int j=s;j>=0;--j) { if(i==n&&j==s) continue; double p1 = 1.0 * i * j; double p2 = 1.0 * (n - i) * j; double p3 = 1.0 * (s - j) * i; double p4 = 1.0 * (n - i) * (s - j); dp[i][j] = (p2 * dp[i+1][j] + dp[i][j+1] * p3 + dp[i+1][j+1] * p4 + n*s) / (n*s - p1); } printf("%.4lf ",dp[0][0]); return 0; }