概率DP(放棋子)Domination
题意:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827369874
给你n*m的棋盘,我们定义放满棋盘是:任意一行一列至少有一个棋子。
问你放满棋盘需要棋子的期望数。
思路:
我们先算出用x个棋子放满棋盘的概率,然后求Sigma就可以了
我们可以转换一下放棋子的方式,在任意一个地方放棋子,我们都可以把这个位置尽可能的移到左上角。
dp【k】【i】【j】是放了k个棋子,已经有 i 行 j 列满了的概率;
注意:放最后一个的时候不需要加放在 i,j区域里的概率(既然都放里面了,那就已经放满了)。
1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0); 2 #include <cstdio>//sprintf islower isupper 3 #include <cstdlib>//malloc exit strcat itoa system("cls") 4 #include <iostream>//pair 5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\草稿.txt","r",stdin); 6 #include <bitset> 7 //#include <map> 8 //#include<unordered_map> 9 #include <vector> 10 #include <stack> 11 #include <set> 12 #include <string.h>//strstr substr 13 #include <string> 14 #include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9; 15 #include <cmath> 16 #include <deque> 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less 18 #include <vector>//emplace_back 19 //#include <math.h> 20 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor 21 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare) 22 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation 23 #define fo(a,b,c) for(register int a=b;a<=c;++a) 24 #define fr(a,b,c) for(register int a=b;a>=c;--a) 25 #define mem(a,b) memset(a,b,sizeof(a)) 26 #define pr printf 27 #define sc scanf 28 #define ls rt<<1 29 #define rs rt<<1|1 30 typedef long long ll; 31 void swapp(int &a,int &b); 32 double fabss(double a); 33 int maxx(int a,int b); 34 int minn(int a,int b); 35 int Del_bit_1(int n); 36 int lowbit(int n); 37 int abss(int a); 38 //const long long INF=(1LL<<60); 39 const double E=2.718281828; 40 const double PI=acos(-1.0); 41 const int inf=(1<<30); 42 const double ESP=1e-9; 43 const int mod=(int)1e9+7; 44 const int N=(int)1e6+10; 45 46 double dp[55][55][2510]; 47 48 int main() 49 { 50 // freopen("C:\\Users\\13606\\Desktop\\草稿.txt","r",stdin); 51 int T; 52 sc("%d",&T); 53 while(T--) 54 { 55 int n,m; 56 sc("%d%d",&n,&m); 57 dp[0][0][0]=1.0; 58 for(int k=1;k<=n*m;++k) 59 { 60 for(int i=1;i<=n;++i) 61 { 62 for(int j=1;j<=m;++j) 63 { 64 dp[i][j][k]=dp[i-1][j][k-1]*(n+1-i)*j/(n*m+1-k) 65 +dp[i][j-1][k-1]*(m+1-j)*i/(n*m+1-k) 66 +dp[i-1][j-1][k-1]*(n+1-i)*(m+1-j)/(n*m+1-k); 67 if(i<n||j<m) 68 dp[i][j][k]+=dp[i][j][k-1]*(i*j+1-k)/(n*m+1-k); 69 } 70 } 71 } 72 double ans=0; 73 for(int i=1;i<=n*m;++i) 74 ans+=i*dp[n][m][i]; 75 pr("%.10lf\n",ans); 76 } 77 return 0; 78 } 79 80 /**************************************************************************************/ 81 82 int maxx(int a,int b) 83 { 84 return a>b?a:b; 85 } 86 87 void swapp(int &a,int &b) 88 { 89 a^=b^=a^=b; 90 } 91 92 int lowbit(int n) 93 { 94 return n&(-n); 95 } 96 97 int Del_bit_1(int n) 98 { 99 return n&(n-1); 100 } 101 102 int abss(int a) 103 { 104 return a>0?a:-a; 105 } 106 107 double fabss(double a) 108 { 109 return a>0?a:-a; 110 } 111 112 int minn(int a,int b) 113 { 114 return a<b?a:b; 115 }