zoukankan      html  css  js  c++  java
  • TopCoder[SRM513 DIV 1]:PerfectMemory(500)

    Problem Statement

         You might have played the game called Memoria. In this game, there is a board consisting of N rows containing M cells each. Each of the cells has a symbol on its back. Each symbol occurs on exactly two cells on the board. 



    A move means turning a pair of cells one by one to see the symbols behind them. When the symbols differ, both of the cells are turned on their faces, thus hiding the symbols again. The player should remember the symbols. If the symbols on the backs of the turned cells coincide, the cells stay that way, i.e., don't turn back again. As soon as after some move all the cells on the board are turned (such that all the symbols are simultaneously visible), the game ends. 



    Manao has a perfect memory, so when he sees the symbol behind some cell, he remembers it forever. Manao is trying to finish the game in the least expected number of moves. Find the expected number of moves he will need to accomplish this.

    Definition

        
    Class: PerfectMemory
    Method: getExpectation
    Parameters: int, int
    Returns: double
    Method signature: double getExpectation(int N, int M)
    (be sure your method is public)

    Limits

        
    Time limit (s): 2.000
    Memory limit (MB): 64

    Notes

    - The board Manao plays on is generated as follows. The same set of (N * M) / 2 symbols is used for each generation. The board contents are chosen uniformly among all valid N x M boards.
    - The returned value must have an absolute or relative error less than 1e-9.

    Constraints

    - N will be between 1 and 50, inclusive.
    - M will be between 1 and 50, inclusive.
    - N * M will be even.

    Examples

    0)  
        
    1
    2
    Returns: 1.0
    There are only two cells on the board, so the game always ends in one move.
    1)  
        
    2
    2
    Returns: 2.6666666666666665
    There are four cells. The game may flow in two possible scenarios:

    1) In the first move, Manao turns two cells with equal symbols. The game ends in two moves then and the probability of such a first move is 1/3.

    2) In the first move, Manao turns two cells with different symbols. Then he finishes the game in three moves and the probability of such a first move is 2/3.

    The overall expected number of moves is 1/3 * 2 + 2/3 * 3 = 8/3.
    2)  
        
    2
    3
    Returns: 4.333333333333334
     
    3)  
        
    4
    4
    Returns: 12.392984792984793
     

    题意:你有n*m张卡片,总共n*m/2种,每种有两张。每次操作时你可以翻开两张,若一样,则它们不再翻回去;否则,这两张卡面会向你展示后再翻回去(不改变位置),假设你记忆力很好,能够记住牌的种类。求出至少进行多少次操作,可以使所有牌都同时正面朝上。注意,一次操作翻牌是有先后的,即你可以先翻一张牌,看过其种类后,再决定翻第二张牌。

    题解:

    假设翻到一样的牌,它们就会被消掉。dp[i][j]表示场上还有i+j张牌未被消掉,已经翻开过其中i张牌(即知道其种类),剩下的j张牌还未被翻开过。

    每次操作一定会先翻一张未被翻过的牌,若其与i张牌中的一张对应,则第二张牌一定翻这张,把它们消掉。若是一张新的牌,则第二张牌一定也翻未被翻过的牌。

    计算每种情况出现的概率与期望,以j为阶段、i为状态,进行动态规划。

    代码:

     1 double dp[2502][2502];
     2 class PerfectMemory 
     3 {
     4     public:
     5     double getExpectation(int N, int M) 
     6     {
     7         //$CARETPOSITION$
     8         int n=N*M; dp[0][0]=0;
     9         for(int j=0;j<=n;j++)
    10         for(int i=0;i<=n;i++)
    11         {
    12             if((i==0)and(j==0))continue; dp[i][j]=10000000;
    13             if(i>j)continue; if(i+j>n)continue; if((j-i)%2==1)continue;
    14             dp[i][j]=0; double p,p2,a1;
    15             p=i; p=p/j; p2=1-p;
    16             if((j>0)and(i>0))
    17             {
    18                 dp[i][j]=dp[i][j]+p*(1+dp[i-1][j-1]);
    19             }
    20             double b,c,d;
    21             if(j>1)
    22             {
    23                 b=1; b=b/(j-1); c=j-2-i; c=c/(j-1); d=1-b-c;
    24                 a1=b*(1+dp[i][j-2])+c*(1+dp[i+2][j-2])+d*(2+dp[i][j-2]);
    25                 dp[i][j]=dp[i][j]+p2*a1;
    26             }
    27         }
    28         return dp[0][n];
    29         
    30     }
    31 };
    View Code
  • 相关阅读:
    PostgreSQL 语法
    Linux 上安装 PostgreSQL
    Gitlab基础知识介绍
    Grafana 入门知识介绍
    数据卷容器
    Docker网络详解——原理篇
    Docker网络详细理解-容器网络互通
    搭建Elasitc stack集群需要注意的日志问题
    创建Elasticsearch集群并为它们配置TLS安全通信
    Elastic:为Elastic Docker部署设置安全
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6668558.html
Copyright © 2011-2022 走看看