题目传送门
正解
思路
-
显然,末尾 0 的个数仅和路径中各数 2 和 5 的因子的最小值有关,因为只有 2 和 5 搭配才能产生 0 。
-
当然,如果走了一个 0 ,那么无论如何,都有且仅有一个 0 !
-
所以,分别对 2 和 5 做一遍 DP,取最小值即可。
-
当然,如果有 0 ,答案最大肯定就只能是 1 辣!
-
那么,怎么输出路径呢?
-
比较简单,如果选择走 0 的话,直接按照如下路径走即可:
- 反之,在 DP 的时候记录一下前驱,然后倒推并输出即可。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN(1011);
typedef long long ll;
ll n;
ll qwt[MAXN][MAXN],qwf[MAXN][MAXN];
bool QWQ[MAXN][MAXN];
ll det[MAXN][MAXN],def[MAXN][MAXN],zy,xxxx;
bool qqt[MAXN][MAXN],qqf[MAXN][MAXN];
bool fnzer;
char stk[MAXN];
int cnt;
inline char giegie(bool fk){
return fk?'D':'R';
}
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
ll qwqaq,qwqwq;scanf("%lld",&qwqaq);
QWQ[i][j]=qwqaq;
qwqwq=qwqaq;
while((!(qwqaq%2))&&qwqaq){qwt[i][j]++,qwqaq/=2;}
while((!(qwqwq%5))&&qwqwq){qwf[i][j]++,qwqwq/=5;}
// printf("%d %d %d %d\n",i,j,qwt[i][j],qwf[i][j]);
if(!QWQ[i][j]) zy=j,fnzer=true;
}
}
for(register int i=0;i<=n+5;++i)
for(register int j=0;j<=n+5;++j)
det[i][j]=def[i][j]=1919810;
det[0][1]=det[1][0]=def[0][1]=def[1][0]=0;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(!QWQ[i][j]) continue;
det[i][j]=min(det[i-1][j],det[i][j-1])+qwt[i][j];
qqt[i][j]=(det[i-1][j]<=det[i][j-1]);
def[i][j]=min(def[i-1][j],def[i][j-1])+qwf[i][j];
qqf[i][j]=(def[i-1][j]<=def[i][j-1]);
}
}
if((det[n][n]==1919810)||(fnzer&&(min(det[n][n],def[n][n]))>1)){
printf("1\n");
for(int i=2;i<=zy;++i) printf("R");
for(int i=2;i<=n;++i) printf("D");
for(register int i=zy+1;i<=n;++i) printf("R");
}
else{
printf("%lld\n",min(det[n][n],def[n][n]));
ll xxx=n,yyy=n;cnt=0;
if(det[n][n]<=def[n][n]){
while((xxx>1)||(yyy>1)){
// printf("%d %d\n",xxx,yyy);
stk[++cnt]=giegie(qqt[xxx][yyy]);
xxxx=xxx;
xxx-=qqt[xxx][yyy];
yyy-=(!qqt[xxxx][yyy]);
}
}
else{
// printf("here!");
while((xxx>1)||(yyy>1)){
// printf("%d %d\n",xxx,yyy);
stk[++cnt]=giegie(qqf[xxx][yyy]);
// printf("qwqwqaq:%d\n",cnt);
xxxx=xxx;
xxx-=qqf[xxx][yyy];
yyy-=(!qqf[xxxx][yyy]);
}
}
// printf("fkfkfk %d\n",cnt);
while(cnt>0){
// printf("nonono\n");
printf("%c",stk[cnt]);
--cnt;
}
}
return 0;
}
/*
5
1 1 1 1 0
0 10 0 1 0
0 1 1 1 0
10 1 10 100000 10
0 1 1 1 1
*/