zoj 3822概率dp

Domination



Time Limit: 8 Seconds Memory Limit: 131072 KB Special Judge



Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays chess with his friends. What’s more, he bought a large decorative chessboard with N rows and M columns.

Every day after work, Edward will place a chess piece on a random empty cell. A few days later, he found the chessboard was dominated by the chess pieces. That means there is at least one chess piece in every row. Also, there is at least one chess piece in every column.

“That’s interesting!” Edward said. He wants to know the expectation number of days to make an empty chessboard of N × M dominated. Please write a program to help him.

Input

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

There are only two integers N and M (1 <= N, M <= 50).

Output

For each test case, output the expectation number of days.

Any solution with a relative or absolute error of at most 10-8 will be accepted.

Sample Input

2

1 3

2 2

Sample Output

3.000000000000

2.666666666667

分析: 这是2014年牡丹江现场赛一题==

可以顺着推概率,最后E=p1*n1+p2*n2…..

也可以逆着推期望。

我用的是dp[i][j][k]表示有i行,j列在第k天被控制好了。

那么当第k+1天放棋子的时候就有四种状态转移;

dp[i][j][k+1]*p1

dp[i+1][j][k+1]*p2

dp[i][j+1][k+1]*p3

dp[i+1][j+1][k+1]*p4

这里的概率分别求就行~

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
const int N=66*66;
using namespace std;
int n,m;
double dp[55][55][N];
//dp[i][j][k]表示有i行满足每行至少有一个棋子的条件,有j列满足每列至少有一个棋子的条件,共占据了K个格子

int main()
{
   int T;
   scanf("%d",&T);
   while(T--)
   {
     scanf("%d%d",&n,&m);
     int total=n*m;
     memset(dp,0,sizeof(dp));
     dp[1][1][1]=1.0;

     for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
        for(int k=max(i,j);k<=i*j;k++)
        {
             if(i==n && j==m)break;
             //cout<<i<<" "<<j<<" "<<k<<"  ";
             //printf("%.12lf\n",dp[i][j][k]);
             if(k!=i*j)dp[i][j][k+1]+=(i*j-k)*1.0/(total-k)*dp[i][j][k];
             if(j+1<=m)
             {
              //cout<<i<<" "<<j<<" "<<k<<"  ";
              dp[i][j+1][k+1]+=(i*m-i*j)*1.0/(total-k)*dp[i][j][k];
              // printf("%.12lf\n",dp[i][j+1][k+1]);

             }

             if(i+1<=n)
             {
                dp[i+1][j][k+1]+=(j*n-i*j)*1.0/(total-k)*dp[i][j][k];
             }
             if(i+1<=n && j+1<=m)
             {
              dp[i+1][j+1][k+1]+=(total-i*m-j*n+i*j)*1.0/(total-k)*dp[i][j][k];
             }
        }

        int cnt=max(n*(m-1),m*(n-1))+1;
        double ans=0.0;
        for(int i=max(n,m);i<=cnt;i++)
        {
               ans+=dp[n][m][i]*i;
               //cout<<n<<" "<<m<<" "<<i<<"  ";
               //printf("%.12lf\n",dp[n][m][i]);
               //printf("%.12lf\n",ans);
        }
        printf("%.12lf\n",ans);
   }
   return 0;
}

时间: 2024-10-11 04:32:07

zoj 3822概率dp的相关文章

zoj 3822 概率dp

1 /* 2 题目大意:一个n*m的棋盘,每天放一个棋子,每行每列至少有一个棋子时结束.求达到每行每列至少有一个棋子的天数的数学期望. 3 */ 4 #include <iostream> 5 #include <cstdio> 6 #include <cstring> 7 using namespace std; 8 9 const int maxn=55; 10 double dp[maxn*maxn][maxn][maxn];//放i颗棋子,j行有棋子,k列有棋子

zoj 3640 概率dp

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4808 Background     If thou doest well, shalt thou not be accepted? and if thou doest not well, sin lieth at the door. And unto thee shall be his desire, and thou shalt rule over him. And Cai

zoj 3299 概率dp

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3329 回头重推式子 题解:http://blog.csdn.net/morgan_xww/article/details/6775853#reply 学到: 1.目前做的两道期望的状态转移方程都是从大向小推,定义方式:dp[i][j][k]....  满足i,j,k时,要达到upbound(i),upbound(j),upbound(k),需要XX的期望 2.待定系数的方

ZOJ 3822 可能性DP

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3822 本场比赛之前,我记得.见WALK概率路DP称号.那么它应该是可以考虑的概率DP,十一还特意看了碍着, 当场景.真的OUT了.然后好激动的样子,開始推得二维.然后感觉好难推.发现n仅仅有50.所以就去推三维,然后发现k<max(i,j)的时候,有无用状态,无用状态初始化不会处理,然后认为好像也用不到,可是感觉更稳的还是去推二维,然后就陷入二维--------悲剧了  

zoj 3329 概率dp

看了这么多,也就是个递推 1 /* 2 ZOJ 3329 3 题意:有三个骰子,分别有k1,k2,k3个面. 4 每次掷骰子,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和. 5 当分数大于n时结束.求游戏的期望步数.初始分数为0 6 7 设dp[i]表示达到i分时到达目标状态的期望,pk为投掷k分的概率,p0为回到0的概率 8 则dp[i]=∑(pk*dp[i+k])+dp[0]*p0+1; 9 都和dp[0]有关系,而且dp[0]就是我们所求,为常数 10 设dp[i]=A

zoj 3329 概率dp 环

一个游戏,你手上有三个骰子,分别有k1, k2, k3面.每次投出这三个骰子,得到三个面x, y, z.并且你有一个计数器,如果投出a, b, c, 则计数器归零,否则计数器加上三面之和,计数器初始为零.如果计数器的值大于 n 则游戏胜利.求胜利所需投骰子次数的期望. 以计数器的值为状态,dp[i] 表述计数器的值为i的情况下投骰子的期望.得到转移方程 p[k] 表示投出点数总和为k的概率,k=0时表示投出计数器归零的概率. dp[i] = p[0]*dp[0] + Σ(dp[i+k]*p[k]

zoj 3735 概率dp

Josephina and RPG Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A role-playing game (RPG and sometimes roleplaying game) is a game in which players assume the roles of characters in a fictional setting. Players take responsibil

ZOJ 3822 Domination DP

状态i,j,k为已经有i行,j列放满,放了k个棋子的概率,转移分四种情况(只增加行,只增加列,行列都增加,行列都不增加)讨论即可. #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <climits>

[概率dp] zoj 3822 Domination

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3822 Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays che