zoukankan      html  css  js  c++  java
  • bzoj千题计划189:bzoj1867: [Noi1999]钉子和小球

    http://www.lydsy.com/JudgeOnline/problem.php?id=1867

    dp[i][j] 落到(i,j)的方案数

    dp[i][j]=0.5*dp[i-1][j]   [(i-1,j)位置有钉子] + 0.5*dp[i-1][j-1]    [(i-1.j-1)位置有钉子] + dp[i-1][j-2]    [(i-1,j-2)位置没有钉子]

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    typedef long long LL;
    
    #define N 52
    
    bool nail[N][N];
    
    LL getgcd(LL a,LL b) { return !b ? a : getgcd(b,a%b); }
    
    struct Fraction
    {
        LL molecule,denominator;
    
        void operator = (int p)
        {
            molecule=p;
            denominator=1;
        }
        
        Fraction operator * (Fraction p)
        {
            Fraction c;
            c.molecule=molecule;
            c.denominator=denominator<<1;
            LL gcd=getgcd(c.molecule,c.denominator);
            c.molecule/=gcd;
            c.denominator/=gcd;
            return c;
        }
        
        void operator += (Fraction p)
        {
            if(!denominator) 
            {
                *this=p;
                return;
            }
            Fraction c;
            LL gcd=getgcd(denominator,p.denominator);
            c.denominator=denominator/gcd*p.denominator;
            c.molecule=c.denominator/denominator*molecule+c.denominator/p.denominator*p.molecule;
            *this=c;
        }
        
        bool have()
        {
            return denominator;
        }
        
        void print()
        {
            if(!molecule) denominator=1;
            cout<<molecule<<'/'<<denominator;
        }
        
    }half;
    
    Fraction dp[N][N];
    
    char getc()
    {
        char c;
        while(1)
        {
            c=getchar();
            if(c=='*'||c=='.') return c;
        }
    }
    
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        char c;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=i;++j)
            {
                c=getc();
                if(c=='*') nail[i][j]=true;
            }
        dp[1][1]=1;
        for(int i=2;i<=n+1;++i)
            for(int j=1;j<=i;++j)
            {
    
                if(nail[i-1][j-1] && dp[i-1][j-1].have()) dp[i][j]+=dp[i-1][j-1]*half;
                if(nail[i-1][j] && dp[i-1][j].have()) dp[i][j]+=dp[i-1][j]*half;
                if(!nail[i-2][j-1] && dp[i-2][j-1].have()) dp[i][j]+=dp[i-2][j-1];
            }
        dp[n+1][m+1].print();
    }

    1867: [Noi1999]钉子和小球

    Time Limit: 1 Sec  Memory Limit: 64 MB
    Submit: 880  Solved: 355
    [Submit][Status][Discuss]

    Description

    Input

    第1行为整数n(2<=n<=50)和m(0<=m<=n)。以下n行依次为木板上从上至下n行钉子的信息,每行中‘*’表示钉子还在,‘.’表示钉子被拔去,注意在这n行中空格符可能出现在任何位置。

    Output

    仅一行,是一个既约分数(0写成0/1),为小球落在编号为m的格子中的概pm。既约分数的定义:A/B是既约分数,当且仅当A、B为正整数且A和B没有大于1的公因子。

    Sample Input

    5 2






    Sample Output

    7/16
  • 相关阅读:
    数据加载存储和文件格式
    基本概率分布图的绘制
    pandas处理各类表格数据
    python时间处理
    matplotlib实现数据可视化
    sql学习笔记:表的运算
    sql杂记:一些坑和数据库恢复
    exists关键词和case表达式
    后台工具screen
    SQL函数小记
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8191230.html
Copyright © 2011-2022 走看看