zoukankan      html  css  js  c++  java
  • 【题解】BZOJ P1867 dp

    这题其实并不是在考DP吧。。。


    转移方程显然

    有钉子的情况下落到左右两边概率相等,均为当前概率的一半

    f[i+1][j]+=f[i][j]/2

    f[i+1][j+1]+=f[i][j]/2

    没钉子的话就直接掉在正下方的钉子上,该点的概率加上当前的

    f[i+2][j+1]+=f[i][j]


    然而难点不在dp,在分数输出好吧!

    来自交了n遍才乱搞对的蒟蒻

    我用了一种非常科学的做法

    众所周知,小球在每个位置的平均概率是2ˆn

    所以我们正常算出f[n+1][m+1]后再让它和2ˆn搞一个gcd,将两数同时除以gcd(相当于约分)即可


    code

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    namespace gengyf{
    ll n,m,f[55][55],tot,ans;
    char mp[55][55];
    ll gcd(ll x,ll y){
        if(!y) return x;
        return gcd(y,x%y);
    }
    ll power(ll x,ll y){
        ll q=1;
        while(y){
            if(y%2)
                q*=x;
            y/=2;
            x=x*x;
        }
        return q;
    }
    int main(){
        scanf("%lld%lld",&n,&m);
        tot=power(2,n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
                scanf("%s",&mp[i][j]);
        f[1][1]=tot;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=i;j++){
                if(mp[i][j]=='*')
                    f[i+1][j]+=f[i][j]/2,f[i+1][j+1]+=f[i][j]/2;
                else
                    f[i+2][j+1]+=f[i][j];
            }
        }
        ans=gcd(tot,f[n+1][m+1]);
        f[n+1][m+1]/=ans,tot/=ans;
        printf("%lld/%lld
    ",f[n+1][m+1],tot);
        return 0;
    }
    }
    int main(){
        gengyf::main();return 0;
    }
  • 相关阅读:
    python2.7_1.4_将IPV4地址转换成不同的格式
    大型网站问题的解决方案
    大型网站的标准
    SCP服务实现Linux交互
    SCP服务实现Linux交互
    使用Linux系统中的SSH服务
    向php文件中添加php.ini文件
    让apache与mysql随着系统自动启动
    为apache与mysql创建快捷方式
    安装PHP软件
  • 原文地址:https://www.cnblogs.com/gengyf/p/11203811.html
Copyright © 2011-2022 走看看