zoukankan      html  css  js  c++  java
  • CodeForces B. The least round way(dp)

    题目链接:http://codeforces.com/problemset/problem/2/B


    B. The least round way
    time limit per test
    5 seconds
    memory limit per test
    64 megabytes
    input
    standard input
    output
    standard output

    There is a square matrix n × n, consisting of non-negative integer numbers. You should find such a way on it that

    • starts in the upper left cell of the matrix;
    • each following cell is to the right or down from the current cell;
    • the way ends in the bottom right cell.

    Moreover, if we multiply together all the numbers along the way, the result should be the least "round". In other words, it should end in the least possible number of zeros.

    Input

    The first line contains an integer number n (2 ≤ n ≤ 1000), n is the size of the matrix. Then follow n lines containing the matrix elements (non-negative integer numbers not exceeding 109).

    Output

    In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.

    Sample test(s)
    input
    3
    1 2 3
    4 5 6
    7 8 9
    
    output
    0
    DDRR

    题意:

    从左上到右下!

    选出一条能让走过的路径的数字的积中含有最少的零!

    PS:

    积要含有零仅仅能是2 或者5形成。寻找一条含有2或者5 最少的路径就可以!

    注意推断矩阵中是否有零的情况!


    代码例如以下:

    //http://blog.csdn.net/azheng51714/article/details/8240390
    #include <cstdio>
    #include <cstring>
    const int maxn = 1017;
    int m[2][maxn][maxn];
    int dp[2][maxn][maxn];
    //dp[0][i][j]到i、j时有多少个2;
    //dp[1][i][j]到i、j时有多少个5。
    int vis[2][maxn][maxn];
    int n;
    
    int solve(int mark)
    {
        vis[mark][1][1] = 0;
        dp[mark][1][1] = m[mark][1][1];
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                if(i==1 && j==1)
                    continue;
                if(i == 1)
                {
                    dp[mark][i][j] = dp[mark][i][j-1] + m[mark][i][j];
                    vis[mark][i][j] = 1;//向右
                }
                else if(j == 1)
                {
                    dp[mark][i][j] = dp[mark][i-1][j] + m[mark][i][j];
                    vis[mark][i][j] = 0;//向下
                }
                else
                {
                    int tt1 = dp[mark][i-1][j];
                    int tt2 = dp[mark][i][j-1];
                    if(tt1 < tt2)
                    {
                        dp[mark][i][j] = tt1 + m[mark][i][j];
                        vis[mark][i][j] = 0;
                    }
                    else
                    {
                        dp[mark][i][j] = tt2 + m[mark][i][j];
                        vis[mark][i][j] = 1;
                    }
                }
            }
        }
        return dp[mark][n][n];
    }
    
    void print(int mark, int x, int y)
    {
        if(x==1 && y==1)
            return ;
        if(vis[mark][x][y] == 0)
        {
            print(mark,x-1,y);
            printf("D");
        }
        else
        {
            print(mark,x,y-1);
            printf("R");
        }
    }
    
    int main()
    {
        int x, y;
        while(~scanf("%d",&n))
        {
            int tt, t1, t2;
            memset(vis,0,sizeof(vis));
            memset(m,0,sizeof(m));
            int flag = 0;
            for(int i = 1; i <= n; i++)
            {
                for(int j = 1; j <= n; j++)
                {
                    scanf("%d",&tt);
                    if(tt == 0)
                    {
                        flag = 1;
                        x = i;
                        y = j;
                        continue;
                    }
                    t1 = t2 = tt;
                    while(t1%2 == 0)
                    {
                        t1/=2;
                        m[0][i][j]++;
                    }
                    while(t2%5 == 0)
                    {
                        t2/=5;
                        m[1][i][j]++;
                    }
                }
            }
    
            int ans1 = solve(0);//路径存在最少的2的个数
            int ans2 = solve(1);//路径存在最少的5的个数
            //printf("ans1:%d ans2:%d
    ",ans1,ans2);
            int mark = 0;
            int ans = 0;
            if(ans1 < ans2)
            {
                ans = ans1;
                mark = 0;
            }
            else
            {
                ans = ans2;
                mark = 1;
            }
            if(flag && ans > 1)
            {
                printf("1
    ");//有零存在那么终于结果就仅仅有一个零
                for(int i = 2; i <= x; i++)
                {
                    //向下到有零的那一行
                    printf("D");
                }
                for(int j = 2; j <= n; j++)
                {
                    //走到最右边
                    printf("R");
                }
                for(int i = x+1; i <= n; i++)
                {
                    //走到最下边
                    printf("D");
                }
                printf("
    ");
                continue;
            }
            printf("%d
    ",ans);
            print(mark, n, n);
            printf("
    ");
        }
        return 0;
    }
    
    /*
    3
    4 10 5
    10 9 4
    6 5 3
    3
    4 10 5
    6 0 2
    7 8 9
    */
    


  • 相关阅读:
    阿里云ECS网站备案流程
    python学习之os.walk()
    python学习之pypandoc
    linux下的which
    python学习之range()和xrange()
    Python内置函数之repr()
    python学习之字典
    SQL基础之聚合与排序
    SQL基础教程
    lombok的安装
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7182674.html
Copyright © 2011-2022 走看看