• CF2B The least round way(贪心+动规)


    题目

    CF2B The least round way

    做法

    后面(0)的个数,(2)(5)(10)分解质因数

    则把方格中的每个数分解成(2)(5),对(2)(5)求两边动规,得出最小值(ans=min(num_2,num_5))

    我们贪心地选择最小值所对应的(2)(5),然后从((n,n))按动规路径返回

    Code

    #include<bits/stdc++.h>
    typedef int LL;
    const LL maxn=1e3+9;
    inline LL Read(){
        LL x(0),f(1); char c=getchar();
        while(c<'0' || c>'9'){
            if(c=='-') f=-1; c=getchar();
        }
        while(c>='0' && c<='9'){
            x=(x<<3)+(x<<1)+c-'0'; c=getchar();
        }return x*f;
    }
    LL n,m,ax,ay,flag;
    LL p[2][maxn][maxn],dp[2][maxn][maxn],a[maxn][maxn];
    void Solve(LL x,LL y,LL op){
        if(x==1 && y==1) ;
        else if(x==1){
            Solve(x,y-1,op); printf("R");
        }else if(y==1){
            Solve(x-1,y,op); printf("D");
        }else{
            if(dp[op][x][y-1]==dp[op][x][y]-p[op][x][y]) Solve(x,y-1,op),printf("R");
            else Solve(x-1,y,op),printf("D");
        }
    }
    int main(){
        n=m=Read();
        for(LL i=1;i<=n;++i)
            for(LL j=1;j<=m;++j){
            	a[i][j]=Read();
            	if(!a[i][j]){
            		ax=i; ay=j;
            		flag=true;
                }
                while(a[i][j]%2==0 && a[i][j]){
                    ++p[0][i][j]; a[i][j]/=2;
                }
                while(a[i][j]%5==0 && a[i][j]){
                    ++p[1][i][j]; a[i][j]/=5;
                }
            }
        for(LL i=1;i<=n;++i)
            for(LL j=1;j<=m;++j){
            	if(i==1 && j==1){
            		dp[0][i][j]=p[0][i][j];
            		dp[1][i][j]=p[1][i][j];
                }else{
                    if(i==1){
                        dp[0][i][j]=dp[0][i][j-1]+p[0][i][j];
                        dp[1][i][j]=dp[1][i][j-1]+p[1][i][j];
                    }else if(j==1){
                        dp[0][i][j]=dp[0][i-1][j]+p[0][i][j];
                        dp[1][i][j]=dp[1][i-1][j]+p[1][i][j];
                    }else{
                        dp[0][i][j]=std::min(dp[0][i-1][j],dp[0][i][j-1])+p[0][i][j];
                        dp[1][i][j]=std::min(dp[1][i-1][j],dp[1][i][j-1])+p[1][i][j];
                    }
                }
            }
        LL ans(std::min(dp[0][n][m],dp[1][n][m]));
        if(ans>1 && flag){
            puts("1");
            for(LL i=1;i<ax;++i) printf("D");
            for(LL i=1;i<ay;++i) printf("R");
            for(LL i=ax;i<n;++i) printf("D");
            for(LL i=ay;i<m;++i) printf("R");
            return 0;
        }
        printf("%d
    ",ans);
        if(ans==dp[0][n][m]){
            Solve(n,m,0);
        }else{
            Solve(n,m,1);
        }
        return 0;
    }
    
  • 相关阅读:
    17字符串函数
    16数学函数
    计算文件的相对路径
    PHP生成唯一ID的方法
    PHP高效产生m个n范围内的不重复随机数(m<=n)
    随机红包
    约瑟夫环问题
    求n以内的质数(质数的定义:在大于1的自然数中,除了1和它本身意外,无法被其他自然数整除的数)
    10个值得深思的_PHP_面试问题
    PHP中被忽略的性能优化利器:生成器
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10966316.html
Copyright © 2020-2023  润新知