zoukankan      html  css  js  c++  java
  • BZOJ 1867 [Noi1999]钉子和小球 DP

    想状态和钉子的位置如何匹配想了半天。。。后来发现不是一样的吗$qwq$


    思路:当然是$DP$啦

    提交:>5次(以为无故$RE$,实则是先乘后除爆了$longspace long$)

    题解:

    若有钉子,左右各乘$frac{1}{2}$转移,否则,向下两层直接转移。

    对于分数,分别维护分子和分母,然后加起来的时候,记着一定要写成

    up[i][j]=up[i][j]*(b/G)+a*(dn[i][j]/G);
    dn[i][j]=dn[i][j]*(b/G);

    而非

    up[i][j]=up[i][j]*b/G+a*dn[i][j]/G;
    dn[i][j]=dn[i][j]*b/G;

    (好吧也是我傻$qwq$)

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ull unsigned long long
    #define ll long long
    #define R register ll 
    #define pause (for(R i=1;i<=10000000000;++i))
    #define In freopen("NOIPAK++.in","r",stdin)
    #define Out freopen("out.out","w",stdout)
    namespace Fread {
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    } inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
    inline void gs(char* s) {
        register char ch; while(isempty(ch=getchar()));
        do *s++=ch; while(!isempty(ch=getchar()));
    }
    } using Fread::g; using Fread::gs;
    namespace Luitaryi {
    const int N=60;
    int n,m;
    ll up[N][N],dn[N][N];
    bool w[N][N];
    inline ll gcd(ll a,ll b){
        return b?gcd(b,a%b):a;
    }
    inline void add(int i,int j,ll a,ll b) {
        R G=gcd(dn[i][j],b);
        up[i][j]=up[i][j]*(b/G)+a*(dn[i][j]/G);
        dn[i][j]=dn[i][j]*(b/G);
        G=gcd(up[i][j],dn[i][j]); 
        if(G) up[i][j]/=G,dn[i][j]/=G;
    }
    inline void main() {
        n=g(),m=g()+1;
        for(R i=1;i<=n;++i) for(R j=1;j<=i;++j) { register char ch;
            while(ch=getchar(),ch!='*'&&ch!='.'); 
            w[i][j]=(ch=='*');
            up[i][j]=0,dn[i][j]=1;
        } for(R i=1;i<=n;++i) up[n+1][i]=0,dn[n+1][i]=1;
        up[1][1]=dn[1][1]=1;
        for(R i=1;i<=n;++i) for(R j=1;j<=i;++j) {
            R a=up[i][j],b=dn[i][j];
            if(w[i][j]) {
                if(a%2==0) a/=2; else b*=2;
                add(i+1,j,a,b),add(i+1,j+1,a,b);
            } else add(i+2,j+1,a,b);
        } printf("%lld/%lld",up[n+1][m],dn[n+1][m]);
        
    }
    }
    signed main() {
        Luitaryi::main();    
    }

    2019.07.17

  • 相关阅读:
    C语言(北京理工大学MOOC 上)
    四则运算、进制转换、变量内存分配
    C语言(挑战ACM-ICPC,DEVFORGE学编程社区)
    迭代公式求平方根
    C语言(数据结构,DEVFORGE学编程社区)
    C语言(复杂数据,DEVFORGE学编程社区)
    C语言(字符串,DEVFORGE学编程社区)
    c语言(北京理工大学mooc 下)
    华中农业大学mooc编程题
    Java通过POI读取Excel
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11204464.html
Copyright © 2011-2022 走看看