[CF2B] The least round way - dp

Given an n × n square matrix of a non-negative integers, you need to find a path:

The upper left corner as a starting point

You can only go to the right or down

To the lower right corner as the end point and, if the number we encountered along the way are multiplied, the product should be minimal "round", in other words, should be a minimum number of 0's end.

Solution

Taking into account the final answer depends only on (2,5 \) \ number of factors that a minimum, it can be considered apart, then that is a simple minimal and the path dp

Note that if the original matrix contains zero, and the answer to \ (1 \) take minit

#include <bits/stdc++.h>
using namespace std;

vector <int> pat;
int n,a[1005][1005],x[1005][1005],f[1005][1005],ans=1e+9;

void solve(int p) {
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++){
            a[i][j]=0;
            int t=x[i][j];
            while(t && t%p==0) t/=p, a[i][j]++;
        }
    }
    memset(f,0x3f,sizeof f);
    f[0][1]=0;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            f[i][j]=min(f[i-1][j],f[i][j-1])+a[i][j];
        }
    }
    /*for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) cout<<f[i][j]<<" ";
        cout<<endl;
    }*/
    vector <int> v;
    {
    int p=n,q=n;
    while(p!=1 && q!=1) {
        int i=p, j=q;
        if(f[i][j]==f[i-1][j]+a[i][j]) {
            v.push_back(1); //cout<<"up";
            --p;
        }
        else if(f[i][j]==f[i][j-1]+a[i][j]) {
            v.push_back(0); //cout<<"left";
            --q;
        }
        else cout<<"err";
    }
    while(p!=1) {
        --p;
        v.push_back(1);
    }
    while(q!=1) {
        --q;
        v.push_back(0);
    }
    reverse(v.begin(),v.end());
    if(f[n][n]<ans) {
        ans=f[n][n];
        pat=v;
    }
    }
}

int main() {
    scanf("%d",&n);
    int flag=0,posx,posy;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            scanf("%d",&x[i][j]);
            if(x[i][j]==0) flag=1,posx=i,posy=j;
        }
    }
    solve(2);
    solve(5);
    if(ans>1 && flag) {
        cout<<1<<endl;
        for(int i=1;i<posx;i++) cout<<"D";
        for(int i=1;i<posy;i++) cout<<"R";
        for(int i=posx;i<n;i++) cout<<"D";
        for(int i=posy;i<n;i++) cout<<"R";
        return 0;
    }
    cout<<ans<<endl;
    for(int i=0;i<pat.size();i++) {
        cout<<(pat[i]?"D":"R");
    }
}

Guess you like

Origin www.cnblogs.com/mollnn/p/12273813.html