题目:
给定一个N*M的矩阵,记录左上角为(1,1),右下角为(N,M),现在从(1,1)开始取数,每次只能向下或向右移动一个单位,最终到达(N,M),我们把路径上所有的数相乘,记为C。使C的结果最大已经不能满足我们了,现在我们想让C末尾的零最少。 Ps.11000末尾有3个零,100000100末尾有2个零。
分析:
一开始用了暴力DFS才三十分。
由题意可以得我们要使路径上的2和5的因子个数尽量少,可以枚举两次,用min1记录最少2的路径和用min2记录最少5的路径,最后结果min(min1,min2)
附上代码:
const maxn=1000; var n,m:longint; two,five,f:array [0..maxn,0..maxn] of longint; procedure init; var i,j,k,temp:longint; begin readln(n,m); for i:=1 to n do for j:=1 to m do begin k:=0; read(temp); while temp mod 2=0 do begin inc(k); temp:=temp div 2; end; two[i,j]:=k; k:=0; while temp mod 5=0 do begin inc(k); temp:=temp div 5; end; five[i,j]:=k; end; end; function min(x,y:longint):longint; begin if x<y then exit(x); exit(y); end; procedure main; var i,j,tott,totf:longint; begin for i:=1 to n do for j:=1 to m do if i=1 then f[i,j]:=f[i,j-1]+two[i,j] else if j=1 then f[i,j]:=f[i-1,j]+two[i,j] else f[i,j]:=min(f[i-1,j],f[i,j-1])+two[i,j]; tott:=f[n,m]; fillchar(f,sizeof(f),0); for i:=1 to n do for j:=1 to m do if i=1 then f[i,j]:=f[i,j-1]+five[i,j] else if j=1 then f[i,j]:=f[i-1,j]+five[i,j] else f[i,j]:=min(f[i-1,j],f[i,j-1])+five[i,j]; totf:=f[n,m]; write(min(tott,totf)); end; begin init; main; end.