1. 程式人生 > >【Codeforces】CF 2 B The least round way(dp)

【Codeforces】CF 2 B The least round way(dp)

clu 更新 .org ORC 我們 std 預處理 blank putc

題目

傳送門:QWQ

分析

求結尾0的數量QwQ。

10只能是$ 2 \times 5 $,我們預處理出每個數因子中2和5的數量。

我們接著dp出從左上到右下的經過的最少的2的數量和最少的5的數量。兩者取min後就是答案。

特判數據中有0的情況,把他當做10處理。如果此時答案大於1,那麽把答案更新成1。因為0只有1個0。

輸出也有些小技巧

代碼

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1005;
 4 int a[maxn][maxn][2], dp[maxn][maxn][2
]; 5 void print(int x,int y,int k,int state){ 6 7 if(x<=0 || y<=0) return; 8 if(dp[x-1][y][k]==dp[x][y][k]-a[x][y][k]) print(x-1,y,k,0); 9 else print(x,y-1,k,1); 10 11 if(state==2) return; 12 if(state==1) putchar(R); 13 else putchar(D); 14 } 15 16 int
main(){ 17 int n, posx, posy, flag=0; 18 scanf("%d",&n); 19 for(int i=1;i<=n;i++) { 20 for(int j=1;j<=n;j++) { 21 int num; scanf("%d",&num); 22 if(!num) { 23 posx=i;posy=j; flag=1; 24 a[i][j][0]=a[i][j][1
]=1; continue; 25 } 26 while(num%2==0) a[i][j][0]++,num/=2; 27 while(num%5==0) a[i][j][1]++,num/=5; 28 } 29 } 30 31 memset(dp,127,sizeof(dp)); 32 dp[1][1][0]=dp[1][1][1] =0; 33 for(int i=1;i<=n;i++){ 34 for(int j=1;j<=n;j++){ 35 for(int k=0;k<2;k++){ 36 dp[i][j][k] = min (min(dp[i][j-1][k],dp[i-1][j][k]), dp[i][j][k]) + a[i][j][k]; 37 } 38 } 39 } 40 int ans=min(dp[n][n][1],dp[n][n][0]); 41 if(flag && ans>1){ 42 printf("%d\n",1); 43 for(int i=1;i<posx;i++) putchar(D); 44 for(int i=1;i<posy;i++) putchar(R); 45 for(int i=posx+1;i<=n;i++) putchar(D); 46 for(int i=posy+1;i<=n;i++) putchar(R); 47 return 0; 48 } 49 printf("%d\n",ans); 50 if(dp[n][n][1] > dp[n][n][0]) print(n,n,0,2); 51 else print(n,n,1,2); 52 return 0; 53 }

【Codeforces】CF 2 B The least round way(dp)