• 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
    */
    


  • 相关阅读:
    C语言实现用户输入
    QQ头像一键添加校徽
    csu oj Infected Computer 1427
    质数个数
    stl实现结构体排序关键语法要点(sort)
    理解 PHP 中的 Streams
    几款主流PHP框架的优缺点评比
    8个开发必备的PHP功能
    5个开发人员不应该错过的最好跨平台PHP编辑器
    推荐五款优秀的PHP代码重构工具
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7182674.html
Copyright © 2020-2023  润新知