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


  • 相关阅读:
    什么是根文件系统
    构建基本的嵌入式Linux根文件系统
    “文件系统”与“根文件系统”详解
    C#中NameValueCollection类用法详解
    别把西红柿连续种在同一块地里
    asp.net 服务器控件的 ID,ClientID,UniqueID 的区别
    不要为框架作过多的假设
    构件技术
    asp.net中控件id,clientid,uniqueid的区别
    系统架构图怎么画
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7182674.html
Copyright © 2011-2022 走看看