方格取数

来源:互联网 发布:淘宝中国质造入口 编辑:程序博客网 时间:2024/04/30 11:06

Description

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

Input

  输入文件matrix.in的第一行包含两个正整数N,M表示矩阵大小。
  接下来N行每行M个正整数给出整个矩阵。

Output

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

Sample Input

3 3

1 2 3

10 5 100

10 8 9

Sample Output

1

Data Constraint

Hint

【数据规模和约定】
  30%的数据满足 N , M ≤ 5;
  100%的数据满足 1 < N , M ≤ 1000,所有输入数据不超过32位整范围。

 

分析:一看到末尾0,就能想起质因数2*5=10。也就是说有一个矩阵,对答案有贡献的只有这个数2的因数个数和5的因数个数。首先预处理出每个数的2,5因数个数。

对于样例,可得

      0 1 0    0 0 0

A=1 0 2   B=1 1 2

     1 3 0    1 0 0

 

我们知道,对于任何一条路径,a为2因数的总数,b为5因数的总数,他的答案就是路径上min(a,b)。我们只需求出两个图中(1,1)à(n,m)的2,5因数最小值,再在这两个最小值中取最小值。证明:我们求出的第一条路径为2因数最小的,如果答案想更小,那么一定要5的因数比他小,而第二条路径是5最小的。如果第二条没有第一条大,那第一条就是最优的,否则第二条为最优的。

 

程序:

var

 a,b:array[0..1000,0..1000] of longint;

 n,m:longint;

 

procedure init;

 vari,j,s,t:longint;

begin

 readln(n,m);

 fori:=1 to n do

  forj:=1 to m do

   begin

   t:=0;

    read(s);

    whiles mod 2=0 do

     begin

     inc(t);

     s:=s div 2;

     end;

   a[i,j]:=t;

   t:=0;

    whiles mod 5=0 do

     begin

     inc(t);

     s:=s div 5;

     end;

   b[i,j]:=t;

   end;

end;

 

function min(x,y:longint):longint;

 begin

  ifx<y then exit(x)

        else exit(y);

 end;

 

procedure dp;

 vari,j,ansa,ansb:longint;

    f:array [0..1000,0..1000] of longint;

begin

 fori:=1 to n do

  forj:=1 to m do

  ifi=1 then f[i,j]:=f[i,j-1]+a[i,j]

  else

   begin

    ifj=1 then f[i,j]:=f[i-1,j]+a[i,j]

          else f[i,j]:=min(f[i-1,j],f[i,j-1])+a[i,j];

   end;

 ansa:=f[n,m];

 fillchar(f,sizeof(f),0);

 fori:=1 to n do

  forj:=1 to m do

   ifi=1 then f[i,j]:=f[i,j-1]+b[i,j]

  else

   begin

    ifj=1 then f[i,j]:=f[i-1,j]+b[i,j]

          else f[i,j]:=min(f[i-1,j],f[i,j-1])+b[i,j];

   end;

 ansb:=f[n,m];

 writeln(min(ansa,ansb));

end;

 

begin

 init;

 dp;

end.

 

 

 

0 0
原创粉丝点击