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


  • 相关阅读:
    神不在的星期天
    炸弹问题——一种会引发死锁的情景模式
    JavaScript的类和继承
    没有功劳也有苦劳
    使用http代理服务器解决本地客户端页面的跨域AJAX问题
    04数组 字符数组
    01 数据类型 、常量变量、运算符、表达式、格式化输入输出
    03循环结构
    .NET编译、WOW64注册表访问、同时在X86和X64平台上部署应用程序
    Vistual Studio 2008中的智能感应功能
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7182674.html
Copyright © 2011-2022 走看看