[笔记] 概率DP ZOJ-3822

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5376
dp[i][j][k] 表示用k天时间使得 以[i][j]为右下角的矩阵达到dominated状态的概率
使用当前状态值递推出四种k+1天的状态值
即:
[1] k+1天 dominated状态的矩阵仍为[i][j]
dp[i][j][k+1]+=dp[i][j][k]*(i*j-k)/(n*m-k)
[2] k+1天 控制了新的一行
[3] k+1天 控制了新的一列
[4] k+1天 控制了新一行和新一列
dp[i][j+1][k+1]+=dp[i][j][k]*(m-j)*i/(n*m-k);
dp[i+1][j+1][k+1]+=dp[i][j][k]*(n-i)*(m-j)/(n*m-k) ;

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


#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
double dp[55][55][55*55];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        dp[1][1][1]=1;

        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                for(int k=1;k<i*j;k++)
                {
                    if(i==n&&j==m)
                        break;
                    dp[i][j][k+1]+=dp[i][j][k]*(i*j-k)/(n*m-k);
                }
                for(int k=1;k<=i*j;k++)
                {
                    dp[i+1][j][k+1]+=dp[i][j][k]*(n-i)*j/(n*m-k);
                    dp[i][j+1][k+1]+=dp[i][j][k]*(m-j)*i/(n*m-k);
                    dp[i+1][j+1][k+1]+=dp[i][j][k]*(n-i)*(m-j)/(n*m-k);
                }
            }
        }
        double sum=0;
        for(int i=1;i<=n*m;i++)
            sum+=dp[n][m][i]*i;
        printf("%.12f\n",sum);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值