http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5376
Meaning of the questions: each row to n * m on the board every day to put a pawn, the board can ask how many days each column has at least a pawn expectations
Analysis: We analyze the wave; explain my weak weak problem-solving ideas
(1) First, it is conceivable to set up a dp [val] represents the current val spent a few days there is a probability flag from the target state. But we can find a simple state val is not accurate status shown , for example, now I know just how much the use of the flag, not currently know how many rows and columns there is a flag;
(2) so we changed to dp dp [val] [i] [j] is represented by a flag of val, there i rows and j columns with flags, and a few days to a target state of probability. Note that we set the probability dp [val] [i] [ j] is a state val few days, so we can put 3 seek out the probability, and finally calculate the expected
(3) state transition: There are four states
(1) is added to a record in rows and columns: dp [val + 1] [i] [j] -> dp [val] [i] [j] * p1;
(2) is added in a row he had not recorded in the recording through the column: dp [val + 1] [i + 1] [j] -> dp [val] [i] [j] * p2;
(3) adding a record is placed over the row and column had no record of: dp [val + 1] [i] [j + 1] -> dp [val] [i] [j] * p3;
(4) is added in a row and column not recorded not recorded over in: dp [val + 1] [i + 1] [j + 1] -> dp [val] [i] [j] * p4;
p1, p2, p3, p4 can be observed that the method for finding FIG:
The red areas j rows and k columns can be considered to have at least a piece of
#include<bits/stdc++.h> using namespace std; double dp[2501][51][51]; int main() { int t; cin >> t; int k=1; while(t--) { int n,m;scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp)); dp[1][1][1]=1; for(int val=1 ; val<n*m ; val++) ///放其 { for(int i=1 ; i<=n ; i++) { for(int j=1 ; j<=m ; j++) { if(dp[val][i][j]==0) continue; double p1,p2,p3,p4; if( i<n ||j<m){ p1=(i*j-val)*1.0/(n*m-val); dp[val+1][i][j]+=dp[val][i][j]*p1; } p2=j*(n-i)*1.0/(n*m-val); dp[val+1][i+1][j]+=dp[val][i][j]*p2; p3=i*(m-j)*1.0/(n*m-val); dp[val+1][i][j+1]+=dp[val][i][j]*p3; p4=(n-i)*(m-j)*1.0/(n*m-val); dp[val+1][i+1][j+1]+=dp[val][i][j]*p4; } } } double ans=0; for(int val=1 ; val<=n*m ; val++) { ans+=dp[val][n][m]*val; //cout<<dp[val][n][m]<<endl; } printf("%.12f\n",ans); } return 0; }