zoukankan      html  css  js  c++  java
  • XJOI 3870 游戏的期望

    题意

    有一个游戏平板上面有(n* m)个格子,一开始每个格子都是关闭的,每个格子里面都有一个标记
    已知每种标记恰好出现两次,也就是一共有(n∗ m/2)种标记
    规定一次移动为依次(one by one不是同时)打开一对格子查看里面的标记,如果标记不一样,格子会自动关闭,但是你的记忆是超强了,看过了就不会忘,如果标记是一样的,格子从此就一直保持打开状态,当所有格子都打开时游戏结束
    请算出游戏结束的最少期望步数

    输入格式

    输入一行包含两个整数(N,M (1≤N≤50,1≤M≤50))
    (N∗ M)是偶数

    输出格式
    输出一个浮点数.误差不超过(1e−9)

    样例1

    1 2
    
    1.0
    

    样例2

    2 2
    
    2.6666666666666665
    

    样例3

    2 3
    
    4.333333333333334
    

    样例4

    4 4
    
    12.392984792984793
    

    分析

    这是一道期望dp(概率dp)题。
    (dp[i][j]) 表示还有 (i+j) 张牌未匹配,已翻开 (i) 张,未翻开 (j) 张。

    状态转移分类讨论:

    从剩下 (j) 张牌中选择一张 (A)

    1.恰好与已翻开的i张中的一张 (B) 匹配,则翻开 (B)

    2.未与已翻开的匹配,则再随机翻一张 (B)

    (1) (A,B) 刚好匹配;

    (2) (A,B)不匹配,也没有与已翻开的匹配;

    (3) (B) 与已翻开的 (i) 张中的一张 (C) 匹配,则在下一轮中翻开 (B,C)

    转移方程:

    (p) 为1.情况的概率, (b) 为2.(1)情况概率, (c) 为2.(2)情况概率, (d) 为2.(3)情况概率,有$$dp[i][j]=p(1+dp[i-1][j-1])+(1-p)(b(1+dp[i][j-2])+c(1+dp[i+2][j-2])+d*(2+dp[i][j-2]))$$

    另外,注意精度问题

    Code

    #include<cstdio>
    #define maxn 2502
    using namespace std;
    double dp[maxn][maxn];
    //期望dp是倒推的
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	n*=m;
    	for(int j=0;j<=n;j++){
    		for(int i=0;i<=n;i++){
    			if((!i&&!j)||(i>j)||(i+j>n)||((j-i)&1))continue;
    			double p=double(i)/j;
    //p:从剩下j张未翻开的牌中选择一张A,恰好与已翻开的i张中的一张B匹配,则翻开B
    			if(j&&i){
    				dp[i][j]+=p*(1+dp[i-1][j-1]);
    			}
    			if(j>=2){
    				double b=1./(j-1),c=double(j-i-2)/(j-1),d=1-b-c;
    //b:从剩下j张未翻开的牌中选择一张A,未匹配,再随机翻一张B,A,B刚好匹配
    //c:从剩下j张未翻开的牌中选择一张A,未匹配,再随机翻一张B,无任何匹配
    //d:从剩下j张未翻开的牌中选择一张A,未匹配,再随机翻一张B,B与已翻开的i张中的一张C匹配,则在下一轮中翻开B,C 
    				dp[i][j]+=(1-p)*(b*(1+dp[i][j-2])+c*(1+dp[i+2][j-2])+d*(2+dp[i][j-2]));
    			}
    		}
    	}
    	printf("%.11lf",dp[0][n]);
    	return 0;
    }
    
  • 相关阅读:
    TinyMail研究—Camellite的插件系统
    Dual Tone Multifrequency
    Linux PPP 数据收发流程
    这个五一怎么过?
    Linux下的磁盘加密方法
    udev的实现原理
    c语言中程序的循环控制,for语句。
    创建一个函数,将和有n个元素的数组中的key相等的所有元素的下标存储在另一数组中,并返回和key元素相同的元素的个数。
    c语言中数组元素的哨兵查找法
    c语言中数组,一般数组
  • 原文地址:https://www.cnblogs.com/BlogOfchc1234567890/p/9865589.html
Copyright © 2011-2022 走看看