The least round way CodeForces - 2B (DP 矩阵 路径)

题意:n * n的数字矩阵,只能向下走和向右走,要求走的数字的积的后面的0最少,求最少的0和路径之一

题解:0 的情况2 种 2 *  5 和乘以 0,记录每个数字分解的2 和 5 的数量,从左上角到右下角使用dp跑出来分别最少的2 和 5,2 和 5个数中少的那个就是答案,如果矩阵中有0就看跑出来的答案是否大于1即可,用g[][][]数组记录路径,dfs输出路径

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-4
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
typedef long long LL;
typedef long long ll;
const int MAXN = 1e3 + 5;
const int mod = 998244353;

int f[MAXN][MAXN][2];
int g[MAXN][MAXN][2];
void dfs(int x,int y,int k) {
    if(x == 1 && y == 1) return;
    if(g[x][y][k]) {
        dfs(x - 1,y,k);
        putchar('D');
    } else {
        dfs(x, y - 1,k);
        putchar('R');
    }
}
int main()
{
    int n,x = 0,k;
    scanf("%d",&n);
    memset(f,0,sizeof f);
    for(int i = 2; i <= n; i++)
        for(int id = 0; id < 2; id++)
            f[0][i][id] = f[i][0][id] = INF;

    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            scanf("%d",&k);
            if (k == 0) {
                x = i;
            } else {
                while (k % 2 == 0) {
                    f[i][j][0]++;
                    k /= 2;
                }
                while (k % 5 == 0) {
                    f[i][j][1]++;
                    k /= 5;
                }
            }
            for (int id = 0; id < 2; id++) {
                if (f[i - 1][j][id] < f[i][j - 1][id]) {
                    g[i][j][id] = 1;    //往下走
                    f[i][j][id] += f[i - 1][j][id];
                } else {
                    g[i][j][id] = 0;    //往右走
                    f[i][j][id] += f[i][j - 1][id];
                }
            }
//            debug(f[i][j][0]);
//            debug(f[i][j][1]);
//            debug(g[i][j][0]);
//            debug(g[i][j][1]);
        }
    }
    if(f[n][n][1] < f[n][n][0])
        k = 1;
    else
        k = 0;

    if(x && f[n][n][1] > 1) {
        printf("1\n");
        for(int i = 2; i <= x; i++)
            putchar('D');
        for(int i = 2; i <= n; i++)
            putchar('R');
        for(int i = x + 1; i <= n; i++)
            putchar('D');
    } else {
//        debug(k);
        printf("%d\n",f[n][n][k]);
        dfs(n,n,k);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/smallhester/p/11365429.html