方格取数 纪中2541 类dp

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。包含一个整数表示所求最小值。

分析

  首先,如果两个数的积的末尾n个零,那这两个数的质因数里肯定有n对2和5。(多个数也是一样的)
  那么,我们就要使路径上的数所包含的2或5最少。
  先预处理出每个数分别包含的2和5的个数,把2的个数放在一个图里(按原来的顺序)(5也一样)
  然后分别在两幅图找一条个数最小的路径,把两个结果比较,较小的那个就是结果。
  ps:找路径我一开始写成广搜,后来发现可以用类dp的方式

f[i,j]=min(f[i1,j]+a[i,j],f[i,j1]+a[i,j])

const
  dx:array[1..2] of longint=(0,1);
  dy:array[1..2] of longint=(1,0);

var
  i,j,k,z:longint;
  n,m:longint;
  a,b,f:array[0..2000,0..2000] of longint;
  ans:longint;

function max(x,y:longint):longint;
begin
  if x>y
    then exit(y)
    else exit(x);
end;

begin
  readln(n,m);
  for i:=1 to n do
    begin
      for j:=1 to m do
        begin
          read(k);
          z:=k;
          while (z<>0) and (z mod 2=0) do
            begin
              a[i,j]:=a[i,j]+1;
              z:=z div 2;
            end;
          while (z<>0) and (z mod 5=0) do
            begin
              b[i,j]:=b[i,j]+1;
              z:=z div 5;
            end;
        end;
      readln;
    end;
  fillchar(f,sizeof(f),$7f);
  f[0,1]:=0;
  for i:=1 to n do
    for j:=1 to n do
      f[i,j]:=max(f[i-1,j]+a[i,j],f[i,j-1]+a[i,j]);
  ans:=f[n,m];
  fillchar(f,sizeof(f),$7f);
  f[0,1]:=0;
  for i:=1 to n do
    for j:=1 to n do
      f[i,j]:=max(f[i-1,j]+b[i,j],f[i,j-1]+b[i,j]);
  if ans<f[n,m]
    then write(ans)
    else write(f[n,m]);
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值