【动态规划】 方格取数

题目描述

给定一个N*M的矩阵,记录左上角为(1,1),右下角为(N,M),现在从(1,1)开始取数,每次只能向下或向右移动一个单位,最终到达(N,M),我们把路径上所有的数相乘,记为C。使C的结果最大已经不能满足我们了,现在我们想让C末尾的零最少

Ps.11000末尾有3个零,100000100末尾有2个零。

输入输出格式

输入格式:

输入文件matrix.in的第一行包含两个正整数NM表示矩阵大小。

接下来N行每行M个正整数给出整个矩阵。

输出格式:

输出文件名为matrix.out。包含一个整数表示所求最小值。

输入输出样例

3 3

1 2 3

10 5 100

10 8 9

说明

30%的数据满足 N , M ≤ 5;

100%的数据满足 1 < N, M ≤ 1000,所有输入数据不超过32位整范围。

分析

20161105学校考试的第二题,比较简单,得分为100。

这道题是一个很明显的动态规划。我们不难得知,最后C末位的0的个数与我们路上取到的数的因数中2与5的个数有关。

我们知道,一个2和一个5相乘会得到一个0,所以,这道题也就变成了:

从(1,1)到(n,m)分别求出一条含2的个数最少与含5的个数最少的路径

在这两条路径中选择2或5的个数较小的那一条,这条路即是我们要求得的路径

还有一些需要注意的细节问题:

①方格中每个数因子中2和5的个数需要预处理,我在程序中用了w[i][j][0]和w[i][j][1]两个数组来保存

②递推前f[i][j]的边界情况一定要处理好,在代码中我会详细叙述

#include<iostream>
#include<cstdio>
#define MAXM 1001
#define INF 0X7F7F7F7F
using namespace std;
int m,n;
int a[MAXM][MAXM];//a数组为输入数字的数组
int w[MAXM][MAXM][2];//用w数组分别存下方格中每个数因子中2和5的个数
int f[MAXM][MAXM][2];
int cal(int i,int x)//计算2和5的个数 
{
    int cnt=0;
    if(i==2)
        while(x%2==0)
        {
            x/=2;
            cnt++;
        }
    if(i==5)
        while(x%5==0)
        {
            x/=5;
            cnt++;
        }
    return cnt;
}
int main()
{
    //freopen("matrix.in","r",stdin);
    //freopen("matrix.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
        {
            scanf("%d",&a[i][j]);
            w[i][j][0]=cal(2,a[i][j]);//用w[i][j][0]存下2的个数
            w[i][j][1]=cal(5,a[i][j]);//用w[i][j][1]存下5的个数
        }
    for(int i=0;i<=m;i++)//边界的预处理 超出边界的地方视为无穷大 
        f[0][i][0]=f[0][i][1]=INF;
    for(int i=0;i<=n;i++)
        f[i][0][0]=f[i][0][1]=INF;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
        {
            if(i==1&&j==1)//递推前的处理
                f[1][1][0]=w[1][1][0],f[1][1][1]=w[1][1][1];
            else
                f[i][j][0]=min(f[i-1][j][0],f[i][j-1][0])+w[i][j][0],//转移方程
                f[i][j][1]=min(f[i-1][j][1],f[i][j-1][1])+w[i][j][1];
        }
    printf("%d",min(f[n][m][0],f[n][m][1]));//打印出较小的一条路径
    return 0;
}
    原文作者:动态规划
    原文地址: https://blog.csdn.net/qq_33901259/article/details/53046045
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞