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 }

猜你喜欢

转载自www.cnblogs.com/fu3638/p/9104399.html