Codeforces # 2B The least round way (DP ),
Description
There is a positive integer matrix of n * n, you need to find a path from the first column of the First row to the nth column of the n, this minimizes the number of zeros at the end of the value multiplied by the number in the lattice you walk through. The minimum number of outputs.
Input
The first row contains 1 n.
The next n rows have n numbers in each row.
Output
A number indicates the minimum number of zeros at the end.
Sample Input
31 2 34 5 67 8 9
Sample Output
0
Because they are all positive numbers, you only need to calculate 2 or 5 of the minimum. Relatively simple.
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<string>#include<iostream>#include<queue>#include<cmath>#include<map>#include<stack>#include<bitset>using namespace std;#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define CLEAR( a , x ) memset ( a , x , sizeof a )typedef long long LL;typedef pair<int,int>pil;const int INF=0x3f3f3f3f;const int maxn=1010;int dp[maxn][maxn][2];int path[maxn][maxn][2];int mp[maxn][maxn][2];int n;void print(int i,int j){ if(i==1&&j==1) return ; print(path[i][j][0],path[i][j][1]); if(i-path[i][j][0]==1&&j==path[i][j][1]) printf("%c",'D'); else printf("%c",'R');}int main(){ int x,cnt1,cnt2,temp; while(~scanf("%d",&n)) { REPF(i,1,n) { REPF(j,1,n) { scanf("%d",&x); cnt1=cnt2=0;temp=x; while(temp%2==0) { temp/=2; cnt1++; } while(x%5==0) { x/=5; cnt2++; } mp[i][j][0]=cnt1; mp[i][j][1]=cnt2; } } CLEAR(dp,INF); dp[1][1][0]=mp[1][1][0]; dp[1][1][1]=mp[1][1][1]; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { for(int k=0;k<2;k++)//0:2 1:5 { if(i>1&&dp[i][j][k]>dp[i-1][j][k]+mp[i][j][k]) { dp[i][j][k]=dp[i-1][j][k]+mp[i][j][k]; path[i][j][0]=i-1;path[i][j][1]=j; } if(j>1&&dp[i][j][k]>dp[i][j-1][k]+mp[i][j][k]) { dp[i][j][k]=dp[i][j-1][k]+mp[i][j][k]; path[i][j][0]=i;path[i][j][1]=j-1; } } } } printf("%d\n",min(dp[n][n][0],dp[n][n][1]));// print(n,n);// puts(""); } return 0;}/*
Look at Codeforces 2B again:
Description
There is a square matrixNLimit × limitN, Consisting of non-negative integer numbers. You shoshould 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 shocould be the least "round". In other words, it shocould end in the least possible number of zeros.
Input
The first line contains an integer numberN(2 cores ≤ CoresNLimit ≤ limit 1000 ),NIs the size of the matrix. Then followNLines containing the matrix elements (non-negative integer numbers not exceeding109 ).
Output
In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.
Sample Input
Input
31 2 34 5 67 8 9
Output
0DDRR
Source
Not only must the output path be included, but also 0 must be included in the matrix;
Problem: for the path to be output, record the previous State. For 0, if 2 or
The number of 5 is greater than or equal to 1, and the matrix contains 0. In this case, the direct answer is 1 0, and the path only needs to find any
Output the rows and columns where 0 is located.
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<string>#include<iostream>#include<queue>#include<cmath>#include<map>#include<stack>#include<bitset>using namespace std;#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define CLEAR( a , x ) memset ( a , x , sizeof a )typedef long long LL;typedef pair<int,int>pil;const int INF=0x3f3f3f3f;const int maxn=1010;int dp[maxn][maxn][2];int path1[maxn][maxn][2];int path2[maxn][maxn][2];int mp[maxn][maxn][2];int n;void print1(int i,int j){ if(i==1&&j==1) return ; print1(path1[i][j][0],path1[i][j][1]); if(i-path1[i][j][0]==1&&j==path1[i][j][1]) printf("%c",'D'); else printf("%c",'R');}void print2(int i,int j){ if(i==1&&j==1) return ; print2(path2[i][j][0],path2[i][j][1]); if(i-path2[i][j][0]==1&&j==path2[i][j][1]) printf("%c",'D'); else printf("%c",'R');}int main(){ int x,cnt1,cnt2,temp,ans; int sx,sy; while(~scanf("%d",&n)) { int flag=1; CLEAR(mp,0); REPF(i,1,n) { REPF(j,1,n) { scanf("%d",&x); cnt1=cnt2=0;temp=x; if(x==0) { mp[i][j][0]=mp[i][j][1]=1; sx=i;sy=j;flag=0;continue; } while(temp%2==0) { temp/=2; cnt1++; } while(x%5==0) { x/=5; cnt2++; } mp[i][j][0]=cnt1; mp[i][j][1]=cnt2; } } CLEAR(dp,INF); dp[1][1][0]=mp[1][1][0]; dp[1][1][1]=mp[1][1][1]; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { for(int k=0;k<2;k++)//0:2 1:5 { if(i>1&&dp[i][j][k]>dp[i-1][j][k]+mp[i][j][k]) { dp[i][j][k]=dp[i-1][j][k]+mp[i][j][k]; if(!k) { path1[i][j][0]=i-1; path1[i][j][1]=j; } else { path2[i][j][0]=i-1; path2[i][j][1]=j; } } if(j>1&&dp[i][j][k]>dp[i][j-1][k]+mp[i][j][k]) { dp[i][j][k]=dp[i][j-1][k]+mp[i][j][k]; if(!k) { path1[i][j][0]=i; path1[i][j][1]=j-1; } else { path2[i][j][0]=i; path2[i][j][1]=j-1; } } } } } ans=min(dp[n][n][0],dp[n][n][1]); if(ans>=1&&!flag) { printf("%d\n",1); for(int i=0;i<sx-1;i++) printf("%c",'D'); for(int i=0;i<sy-1;i++) printf("%c",'R'); for(int i=sx;i<n;i++) printf("%c",'D'); for(int i=sy;i<n;i++) printf("%c",'R'); puts(""); continue; } printf("%d\n",ans); if(ans==dp[n][n][0]) print1(n,n); else print2(n,n); puts(""); } return 0;}/*32 2 22 2 25 5 5*/