Codeforces 2B The least round way(dp求最小末尾0)

Posted Yeader

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 2B The least round way(dp求最小末尾0)相关的知识,希望对你有一定的参考价值。

题目链接: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,若暗杀>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\n",ans);
112     if(ans==dp[n][n][0])
113         print(n,n,0);
114     else
115         print(n,n,1);
116     return 0;
117 }

 

以上是关于Codeforces 2B The least round way(dp求最小末尾0)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 2B The least round way(dp求最小末尾0)

2B The least round way

code force 2B The least round way

CF2B The least round way

CF2B The least round way 题解

[CF2B] The least round way - dp