题目链接:http://codeforces.com/problemset/problem/2/B
题目大意:
给你一个nxn的矩形,找到一条从左上角到右下角的路径,使得该路径上所有数字的乘积的末尾0最少。
解题思路:
我们设k为2的因子数,m为5的因子数,那么一个数的末尾0的个数就是min(k,m)。
我们设dp[i][j][0]为从左上角到点(i,j)的乘积的最少2因子数,dp[i][j][1]为从左上角到点(i,j)的乘积的最少5因子数。
那么ans=min(dp[i][j][0],dp[i][j][1]),如果ans=dp[i][j][0]就按path[i][j][0]输出,若ans=dp[i][j][1]也同理。
注意存在0的情况,若果路径中有一个0那么末尾0为1,若ans>1,则构造一条经过0的路径输出。
代码:
1 #include<bits/stdc++.h> 2 #define lc(a) (a<<1) 3 #define rc(a) (a<<1|1) 4 #define MID(a,b) ((a+b)>>1) 5 #define fin(name) freopen(name,"r",stdin) 6 #define fout(name) freopen(name,"w",stdout) 7 #define clr(arr,val) memset(arr,val,sizeof(arr)) 8 #define _for(i,start,end) for(int i=start;i<=end;i++) 9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); 10 using namespace std; 11 typedef long long LL; 12 const int N=1e3+5; 13 const int INF=0x3f3f3f3f; 14 const double eps=1e-10; 15 16 int n; 17 int mp[N][N],dp[N][N][2],path[N][N][2]; 18 19 struct node{ 20 int f,s; 21 node(int f,int s):f(f),s(s){} 22 }; 23 24 bool judge(int x,int y){ 25 if(x>0&&x<=n&&y>0&&y<=n) return true; 26 return false; 27 } 28 29 void print(int x,int y,int type){ 30 if(path[x][y][type]==-1) 31 return; 32 if(path[x][y][type]==0) 33 print(x-1,y,type); 34 else 35 print(x,y-1,type); 36 printf("%c",path[x][y][type]==0?'D':'R'); 37 } 38 39 node cal(int x){ 40 int f=0,s=0; 41 while(x){ 42 if(x%5==0){ 43 f++; 44 x/=5; 45 } 46 else break; 47 } 48 while(x){ 49 if(x%2==0){ 50 s++; 51 x/=2; 52 } 53 else break; 54 } 55 return node(f,s); 56 } 57 58 int main(){ 59 scanf("%d",&n); 60 int idx,idy; 61 bool flag=false; 62 memset(path,-1,sizeof(path)); 63 memset(dp,0x3f,sizeof(dp)); 64 for(int i=1;i<=n;i++){ 65 for(int j=1;j<=n;j++){ 66 scanf("%d",&mp[i][j]); 67 if(mp[i][j]==0){ 68 idx=i; 69 idy=j; 70 flag=true; 71 } 72 } 73 } 74 dp[1][1][0]=dp[1][1][1]=0; 75 for(int i=1;i<=n;i++){ 76 for(int j=1;j<=n;j++){ 77 node t=cal(mp[i][j]); 78 if(judge(i-1,j)){ 79 dp[i][j][0]=dp[i-1][j][0]; 80 dp[i][j][1]=dp[i-1][j][1]; 81 path[i][j][1]=path[i][j][0]=0; 82 } 83 if(judge(i,j-1)){ 84 if(dp[i][j][0]>dp[i][j-1][0]){ 85 dp[i][j][0]=dp[i][j-1][0]; 86 path[i][j][0]=1; 87 } 88 if(dp[i][j][1]>dp[i][j-1][1]){ 89 dp[i][j][1]=dp[i][j-1][1]; 90 path[i][j][1]=1; 91 } 92 } 93 dp[i][j][0]+=t.f; 94 dp[i][j][1]+=t.s; 95 } 96 } 97 int ans=min(dp[n][n][0],dp[n][n][1]); 98 if(ans>1&&flag){ 99 puts("1"); 100 for(int i=2;i<=idx;i++){ 101 printf("D"); 102 } 103 for(int j=2;j<=n;j++){ 104 printf("R"); 105 } 106 for(int i=idx+1;i<=n;i++){ 107 printf("D"); 108 } 109 return 0; 110 } 111 printf("%d ",ans); 112 if(ans==dp[n][n][0]) 113 print(n,n,0); 114 else 115 print(n,n,1); 116 return 0; 117 }