codeforces2b the least round way

给出一个矩阵,求从左上角到右下角找出一条路径,使得这条路径上的所有数的乘积后缀0最小。从左上角至右下角的输出路径。

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <math.h>
  5 #include <string.h>
  6 #include <algorithm>
  7 using namespace std;
  8 const int maxn=1005;
  9 int dp[maxn][maxn][4];
 10 int n,len;
 11 char s[2*maxn];
 12 /**
 13 解题思路:
 14 0的个数是有2*5来决定的.对于每个数,质因子分解出2,5的个数。
 15 找出2个数最小的路径l1上最后一个点的2的个数k
 16 找出5个数最小的路径l2上最后一个点的5的个数m
 17 对于l1来说,l2路径上最后一个点的2的个数会不小于k.
 18 对于l2来说,l1路径上最后一个点的5的个数会不小于m.
 19 所以要想使得后缀0最小,也就是min(k,m)最小的数就是解,
 20 对应路径输出即可。
 21 注意0的情况。
 22 0不存在 直接输出路径
 23 0存在,MIN>=1输出可行0路径
 24 0存在,MIN<1输出路径
 25 dp[i][j][0]从左上角到i,j点2的个数最小
 26 dp[i][j][1]从左上角到i,j点5的个数最小
 27 dp[i][j][2]到达2的方向
 28 dp[i][j][3]到达5的方向
 29 
 30 */
 31 void work(int k)
 32 {
 33     int x=n,y=n;
 34     while(x>=1&&y>=1)
 35     {
 36         s[len++]=dp[x][y][k];
 37         if(dp[x][y][k]=='D') x=x-1;
 38         else y=y-1;
 39         if(x==1&&y==1) break;
 40     }
 41 }
 42 int main()
 43 {
 44     int num,flag;
 45     while(scanf("%d",&n)!=EOF)
 46     {
 47         flag=0;
 48         memset(dp,0,sizeof(dp));
 49         for(int i=0; i<=n; i++)
 50         {
 51             dp[0][i][0]=dp[i][0][1]=dp[i][0][0]=dp[0][i][1]=99999999;
 52         }
 53         for(int i=1; i<=n; i++)
 54         {
 55             for(int j=1; j<=n; j++)
 56             {
 57                 scanf("%d",&num);
 58                 if(num==0) flag=i;
 59                     while(num&&num%2==0)
 60                     {
 61                         dp[i][j][0]++;
 62                         num/=2;
 63                     }
 64                 while(num&&num%5==0)
 65                 {
 66                     dp[i][j][1]++;
 67                     num/=5;
 68                 }
 69                 if(i==1&&j==1) continue;
 70                 if(i==1&&j>1)
 71                 {
 72                     dp[i][j][2]=dp[i][j][3]='R';
 73                     dp[i][j][0]+=dp[i][j-1][0];
 74                     dp[i][j][1]+=dp[i][j-1][1];
 75                     continue;
 76                 }
 77                 if(i>1&&j==1)
 78                 {
 79                     dp[i][j][2]=dp[i][j][3]='D';
 80                     dp[i][j][0]+=dp[i-1][j][0];
 81                     dp[i][j][1]+=dp[i-1][j][1];
 82                     continue;
 83                 }
 84                 if(dp[i][j-1][0]<dp[i-1][j][0])
 85                 {
 86                     dp[i][j][0]+=dp[i][j-1][0];
 87                     dp[i][j][2]='R';
 88                 }
 89                 else
 90                 {
 91                     dp[i][j][0]+=dp[i-1][j][0];
 92                     dp[i][j][2]='D';
 93                 }
 94                 if(dp[i][j-1][1]<dp[i-1][j][1])
 95                 {
 96                     dp[i][j][1]+=dp[i][j-1][1];
 97                     dp[i][j][3]='R';
 98                 }
 99                 else
100                 {
101                     dp[i][j][1]+=dp[i-1][j][1];
102                     dp[i][j][3]='D';
103                 }
104             }
105         }
106         int ans5=dp[n][n][1],ans2=dp[n][n][0];
107         len=0;
108         if(flag&&min(ans2,ans5)>=1)///没有考虑   存在0并且结果为0的情况
109         {
110             printf("1
");
111             for(int i=1; i<flag; i++) printf("D");
112             for(int i=1; i<n; i++) printf("R");
113             for(int i=flag; i<n; i++) printf("D");
114             printf("
");
115         }
116         else
117         {
118             if(ans2<ans5)
119             {
120                 printf("%d
",dp[n][n][0]);
121                 work(2);
122             }
123             else
124             {
125                 printf("%d
",dp[n][n][1]);
126                 work(3);
127             }
128             for(int i=len-1; i>=0; i--)
129                 printf("%c",s[i]);
130             printf("
");
131         }
132     }
133     return 0;
134 }
View Code
原文地址:https://www.cnblogs.com/linxhsy/p/4637137.html