1. 程式人生 > >2B The least round way

2B The least round way

tex thml AS tle bre AC 最小值 else HR

傳送門

題目

There is a square matrix n?×?n, consisting of non-negative integer numbers. You should find such a way on it that

  • starts in the upper left cell of the matrix;
  • each following cell is to the right or down from the current cell;
  • the way ends in the bottom right cell.

Moreover, if we multiply together all the numbers along the way, the result should be the least "round". In other words, it should end in the least possible number of zeros.

Input

The first line contains an integer number n (2?≤?n?≤?1000), n is the size of the matrix. Then follow n lines containing the matrix elements (non-negative integer numbers not exceeding 109).

Output

In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.

Examples Input
3
1 2 3
4 5 6
7 8 9
Output
0
DDRR

題目大意

給定由非負整數組成的 n×nn \times nn×n 的正方形矩陣,你需要尋找一條路徑:

以左上角為起點,每次只能向右或向下走

以右下角為終點 並且,如果我們把沿路遇到的數進行相乘,積應當是最小“round”,換句話說,應當以最小數目的0的結尾.

輸入格式

第一行包含一個整數 n ( 2≤n≤10002 \leq n \leq 10002n1000 ),n 為矩陣的規模,接下來的n行包含矩陣的元素(不超過10^9的非負整數).

輸出格式

第一行應包含最小尾0的個數,第二行打印出相應的路徑(譯註:D為下,R為右)

分析

這是一道普通的dp題,因為最小的零的個數就是5的最少個數和2的最少個數的最小值,所以我們進行兩次dp分別求出2和5的數量然後取min。特別得,如果在路徑中經過0則整個過程的0的總數就是1,所以在進行完兩次dp後特判一下即可。

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int n,g[1100][1100],dp[1100][1100],now[1100][1100],best=1000000007;
string ans;
void work(int x,int y){
if(x-1&&dp[x-1][y]+now[x][y]==dp[x][y]){
work(x-1,y);
ans.push_back(‘D‘);
}else if(y-1){
work(x,y-1);
ans.push_back(‘R‘);
}
}
void go(int wh){
int i,j,k;
memset(now,0,sizeof(now));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
while(g[i][j]&&g[i][j]%wh==0){
now[i][j]++;
g[i][j]/=wh;
}
memset(dp,0x3f,sizeof(dp));
dp[1][1]=now[1][1];
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
if(i-1)dp[i][j]=min(dp[i][j],dp[i-1][j]+now[i][j]);
if(j-1)dp[i][j]=min(dp[i][j],dp[i][j-1]+now[i][j]);
}
if(dp[n][n]<best){
ans="";
best=dp[n][n];
work(n,n);
}
}
int main()
{ int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&g[i][j]);
go(2);
go(5);
if(best>1){
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(!g[i][j]){
best=1;
ans="";
for(k=1;k<i;k++)ans.push_back(‘D‘);
for(k=1;k<j;k++)ans.push_back(‘R‘);
for(k=i;k<n;k++)ans.push_back(‘D‘);
for(k=j;k<n;k++)ans.push_back(‘R‘);
break;
}
}
cout<<best<<endl<<ans<<endl;
return 0;
}

2B The least round way