Codeforces 2B - The least round way

时间:2021-07-17 01:58:50

2B - The least round way

思路:

dp。

先算出每个数2因子的个数,和5因子的个数

因为要出现0那么要1个2乘1个5,那么最后的答案是min(2的个数,5的个数)

所以我们可以分开考虑,先算出使2最小的方案,再算出使5最小的方案,然后再取最小就可以了。

注意特判一种情况,如果经过一次0,那么答案只有1个0,再和上面那种情况比较一下,取个最小

mp[i][j][0]表示(i,j)这个位置2因子的个数

mp[i][j][1]表示(i,j)这个位置5因子的个数

状态:dp[i][j][0]表示到(i,j)这个位置2的最小个数

         dp[i][j][1]表示到(i,j)这个位置5的最小个数

初始状态:dp[1][1][0]=mp[1][1][0]

                dp[1][1][1]=mp[1][1][1]

目标状态:dp[n][n][0],dp[n][n][1]

状态转移:dp[i][j][s]=min(dp[i-1][j][s]+mp[i][j][s],dp[i][j-1][s]+mp[i][j][s])

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
#define mkp make_pair
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))

const int N=1e3+5;
int dp[N][N][2],mp[N][N][2];
pii pre[N][N][2];
void dfs(int x,int y,int s){
    if(x==1&&y==1)return ;
    dfs(pre[x][y][s].first,pre[x][y][s].second,s);
    if(pre[x][y][s].first==x-1)cout<<'D';
    else cout<<'R';
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,T,ix,iy;
    cin>>n;
    bool f=false;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>T;
            if(T==0){
                mp[i][j][0]=mp[i][j][1]=1;
                ix=i,iy=j;
                f=true;
                continue;
            }
            int t=0,tt=0;
            while(T%2==0){
                T/=2;
                t++;
            } 
            while(T%5==0){
                T/=5;
                tt++;
            }
            mp[i][j][0]=t;
            mp[i][j][1]=tt;
        }
    }
    mem(dp,0x3f);
    for(int i=0;i<2;i++){
        dp[1][1][i]=mp[1][1][i];
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                if(j==1&&k==1)continue;
                if(dp[j-1][k][i]+mp[j][k][i]<dp[j][k][i]){
                    dp[j][k][i]=dp[j-1][k][i]+mp[j][k][i];
                    pre[j][k][i]=mkp(j-1,k);
                }
                if(dp[j][k-1][i]+mp[j][k][i]<dp[j][k][i]){
                    dp[j][k][i]=dp[j][k-1][i]+mp[j][k][i];
                    pre[j][k][i]=mkp(j,k-1);
                }
            }
        }
    }
    //cout<<dp[n][n][0]<<' '<<dp[n][n][1]<<endl; 
    int s,ans;
    if(dp[n][n][0]<dp[n][n][1])ans=dp[n][n][0],s=0;
    else ans=dp[n][n][1],s=1;
    if(f){
        if(ans>1){
            cout<<1<<endl;
            for(int i=0;i<ix-1;i++)cout<<'D';
            for(int i=0;i<n-1;i++)cout<<'R';
            for(int i=ix-1;i<n-1;i++)cout<<'D';
        }
        else{
            cout<<ans<<endl;
            dfs(n,n,s);
        } 
    }
    else{
        cout<<ans<<endl;
        dfs(n,n,s);
    }
    
    return 0; 
}