D - Domination ZOJ - 概率DP

本文探讨了ZOJ-3822 D-Domination问题,即在一个N*M的棋盘上,每次放置一枚棋子直至每行每列都有棋子,通过动态规划计算放置棋子个数的期望值。关键在于理解状态转移方程,如何计算不同状态下放置棋子的概率,最终求得期望。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • D - Domination

  •  ZOJ - 3822 
  • 题意:给定一个N∗M的棋盘,每次任选一个位置放置一枚棋子,直到每行每列上都至少有一枚棋子,问放置棋子个数的期望。
  • 思路:
  • 注意天数k必须从至少得比max(i,j)大才有可能出现当前的状态
  • dp[i][j][k+1]+=dp[i][j][k]∗(n−k)/(S−k)没有新的行列出现只能从当前行列中选取新点(要出去原来的的点)
  • dp[i+1][j][k+1]+=dp[i][j][k]∗(N−i)∗j/(S−k)出现新的行但没有出现新的列所以可选的点为(n-i)*j
  • dp[i][j+1][k+1]+=dp[i][j][k]∗(M−j)∗i/(S−k)出现新的列但没有出现新的行所以可选的点为(m-j)*i
  • dp[i+1][j+1][k+1]+=dp[i][j][k]∗(N−i)∗(M−j)/(S−k)出现新的列也出现新的行所以可选的点为(m-j)*(n-i).
  • 概率算完了最后求期望 ,能够合法状态的期望但是每个dp里面存了这种状态出现的概率但是一旦有效之后放的就没有用了
  • 所以相邻天数做差之后*天数求和就是期望值。
  • #include<stdio.h>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define maxn 55
    int n,m,s,sp,t;
    double dp[maxn][maxn][maxn*maxn];
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            double ans=0;
            scanf("%d%d",&n,&m);
            memset(dp,0,sizeof(dp));
            dp[1][1][1]=1;
            s=n*m;
            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                {
                    sp=i*j;
                    for(int k=max(i,j); k<=sp; k++)
                    {
                        dp[i][j][k+1]+=dp[i][j][k]*(sp-k)/(s-k);
                        dp[i+1][j][k+1]+=dp[i][j][k]*(n-i)*j/(s-k);
                        dp[i][j+1][k+1]+=dp[i][j][k]*(m-j)*i/(s-k);
                        dp[i+1][j+1][k+1]+=dp[i][j][k]*(n-i)*(m-j)/(s-k);
                    }
                }
            for(int i=max(n,m); i<=m*n; i++)
                ans+=(dp[n][m][i]-dp[n][m][i-1])*i;
            printf("%.9lf\n",ans);
        }
        return 0;
    }
    

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值