Domination

Domination

题目链接:https://odzkskevi.qnssl.com/9713ae1d3ff2cc043442f25e9a86814c?v=1531624384

题意:t组数据 n*m棋盘,让n行m列都存在一个棋子的时候,定义为n*m的棋盘全部被覆盖。最后求期望

思路:涉及到了概率和期望,当然我们第一时间想到的就是概率DP,开始一直在推算状态转移方程的时候。没有乘上没有出现的次数

例如dp[i-1][j][k-1] 我们应该要写成dp[i]-1][j][k-1]*p*((n-i+1)*j),也就是此前没出现过的数.(p为当前的剩余天数分之一)

最后状态转移方程如下

dp[i][j][k]=dp[i][j-1][k-1]*p*((m-j+1)*i)+dp[i-1][j-1][k-1]*p*((n-i+1)*(m-j+1))+dp[i-1][j][k-1]*p*((n-i+1)*j)+dp[i][j][k-1]*(i*j-(k-1))*p

当i==n&&j==m时我们不需要加上dp[i][j][k-1]*(i*j-(k-1))*p;

最后我们累加dp[n][m[i]*i即可 求出期望;

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<ll, int> pll;
#define eps 1e-6
const int INF = 0x3f3f3f3f;
const int maxn = 1000000+5;
const int MOD = 1e9+7;
double dp[55][55][2505];
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);
        memset(dp,0,sizeof(dp));
        dp[0][0][0]=1;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                for(int k=1; k<=n*m; k++)
                {
                    double p=1.0/(n*m-k+1);
                    if(i==n&&j==m) 
                    {
                        dp[i][j][k]=dp[i][j-1][k-1]*p*((m-j+1)*i)+dp[i-1][j-1][k-1]*p*((n-i+1)*(m-j+1))+dp[i-1][j][k-1]*p*((n-i+1)*j);
                    }

                    else
                        dp[i][j][k]=dp[i][j-1][k-1]*p*((m-j+1)*i)+dp[i-1][j-1][k-1]*p*((n-i+1)*(m-j+1))+dp[i-1][j][k-1]*p*((n-i+1)*j)+dp[i][j][k-1]*(i*j-(k-1))*p; 
                }
        double sum=0;
        for(int i=1; i<=n*m; i++)
        {
            sum+=dp[n][m][i]*i;
        }
        printf("%.12lf\n",sum);
    }
}
View Code

PS:摸鱼怪的博客分享,欢迎感谢各路大牛的指点~

猜你喜欢

转载自www.cnblogs.com/MengX/p/9314224.html