码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces B. The least round way(dp)

时间:2014-10-27 23:01:43      阅读:350      评论:0      收藏:0      [点我收藏+]

标签:codeforces   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\n",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\n");//有零存在那么最终结果就只有一个零
            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("\n");
            continue;
        }
        printf("%d\n",ans);
        print(mark, n, n);
        printf("\n");
    }
    return 0;
}

/*
3
4 10 5
10 9 4
6 5 3
3
4 10 5
6 0 2
7 8 9
*/


CodeForces B. The least round way(dp)

标签:codeforces   dp   

原文地址:http://blog.csdn.net/u012860063/article/details/40517115

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!