Codeforces 2B - The least round way

Posted Wisdom+.+

tags:

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

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; 
}

 

以上是关于Codeforces 2B - The least round way的主要内容,如果未能解决你的问题,请参考以下文章

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