zoukankan      html  css  js  c++  java
  • codeforces2B.The least round way 题解 动态规划/模拟

    题目出处:http://codeforces.com/problemset/problem/2/B

    题目描述

    给你一个 (n imes n) 的二维数组,它包含的元素都是非负整数。你需要寻找一条满足如下条件的行走路线:

    • 这条路线的起始位置在二维数组的左上角;
    • 每一步你只可以从当前的位置往右或者往下走一格;
    • 这条路线的终止位置在二维数组的右下角。

    此外,如果我们一路上把所有的数字相乘,结果应该是最不“圆”的。换句话说,这个乘积结尾的 (0) 应该尽可能地少。

    输入格式

    输入的第一行包含一个整数 (n(2 le n le 1000)) ,用于表示二维数组的大小。
    接下来 (n) 行,每行包含 (n) 个元素用于表示这个二维数组(数据保证二维数组的每个元素都是非负整数并且不超过 (10^9) )。

    输出格式

    输出的第一行包含一个整数,用于表示最不圆路线的结尾 (0) 的个数。
    输出的第二行用于表述路线(具体表述方式见样例输出,一个字符 'R' 表示向右走一格,一个字符 'D' 表示向下走一格)。

    样例输入

    3
    1 2 3
    4 5 6
    7 8 9
    

    样例输出

    0
    DDRR
    

    题目分析

    本题涉及算法:动态规划。
    接下来我们来正式将解题思路:
    我们设左上角坐标为 ((0,0)) ,右下角坐标为 ((n-1,n-1)) ,同时我们设:

    • (a[i][j]) :表示数组第 (i) 行第 (j) 列的元素;
    • (num2[i][j]) :表示 (a[i][j]) 最多能分解出的 (2) 的数量;
    • (num5[i][j]) :表示 (a[i][j]) 最多能分解出的 (5) 的数量;
    • (f2[i][j]) :表示从左上角 ((0,0)) 走到 ((i,j)) 的路线上所有数的乘积中包含的最少的 (2) 的数量;
    • (f5[i][j]) :表示从左上角 ((0,0)) 走到 ((i,j)) 的路线上所有数的乘积中包含的最少的 (5) 的数量。

    然后我们可以根据 (f2[n-1][n-1])(f5[n-1][n-1]) 的大小来确定路线:

    • 如果 (f2[n-1][n-1] le f5[n-1][n-1]) ,那我从 ((n-1,n-1))((0,0)) 能够逆推出一条得到 (f2[n-1][n-1]) 的路线,我在一般情况下就是我们的答案;
    • 如果 (f2[n-1][n-1] > f5[n-1][n-1]) ,那我从 ((n-1,n-1))((0,0)) 能够逆推出一条得到 (f5[n-1][n-1]) 的路线,我在一般情况下就是我们的答案。

    注意,这里我说的是“一般情况”,那么什么是非一般情况呢,那就是存在一个元素为 (0) 的情况,那么这个时候又同时满足 (min(f2[n-1][n-1] , f5[n-1][n-1]) > 1) ,那么我们就不应该通过 (f2) 或者 (f5) 去逆推了,而是只需要找一条经过这个数值为 (0) 的位置的路线就可以了。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1010;
    int n, a[maxn][maxn], num2[maxn][maxn], num5[maxn][maxn], f2[maxn][maxn], f5[maxn][maxn];
    stack<char> res;
    void output(int f[][maxn]) {
        cout << f[n-1][n-1] << endl;
        int r = n-1, c = n-1;
        while (r && c) {
            if (f[r-1][c] <= f[r][c-1]) { res.push('D'); r--; }
            else { res.push('R'); c --; }
        }
        while (r) { res.push('D'); r --; }
        while (c) { res.push('R'); c --; }
        while (!res.empty()) {
            putchar(res.top());
            res.pop();
        }
    }
    int main() {
        cin >> n;
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++) {
                cin >> a[i][j];
                while (a[i][j] > 0 && a[i][j] % 2 == 0) {
                    a[i][j] /= 2;
                    num2[i][j] ++;
                }
                while (a[i][j] > 0 && a[i][j] % 5 == 0) {
                    a[i][j] /= 5;
                    num5[i][j] ++;
                }
            }
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++) {
                if (i == 0 && j == 0) {
                    f2[i][j] = num2[i][j];
                    f5[i][j] = num5[i][j];
                }
                else if (i == 0) {
                    f2[i][j] = f2[i][j-1] + num2[i][j];
                    f5[i][j] = f5[i][j-1] + num5[i][j];
                }
                else if (j == 0) {
                    f2[i][j] = f2[i-1][j] + num2[i][j];
                    f5[i][j] = f5[i-1][j] + num5[i][j];
                }
                else {
                    f2[i][j] = min(f2[i-1][j], f2[i][j-1]) + num2[i][j];
                    f5[i][j] = min(f5[i-1][j], f5[i][j-1]) + num5[i][j];
                }
            }
        int r0 = -1, c0 = -1;
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++)
                if (a[i][j] == 0) {
                    r0 = i; c0 = j;
                }
        if (r0 != -1 && min(f2[n-1][n-1], f5[n-1][n-1]) > 1) {  // 如果存在数值为0且f2,f5较小值>1
            int r = 0, c = 0;
            cout << 1 << endl;
            while (c < c0) { putchar('R'); c ++; }
            while (r < r0) { putchar('D'); r ++; }
            while (c < n-1) { putchar('R'); c ++; }
            while (r < n-1) { putchar('D'); r ++; }
        }
        else
            output(f2[n-1][n-1] <= f5[n-1][n-1] ? f2 : f5);
        return 0;
    }
    
  • 相关阅读:
    Nginx Rewrite相关功能-ngx_http_rewrite_module模块指令概述
    Linux操作系统安全-加密和安全扫盲篇
    Nginx安全相关配置-自定义Nginx版本信息
    Nginx高级配置-官网logo之favicon.ico
    Linux操作系统的打包/归档工具介绍
    Nginx高级配置-实现多域名HTTPS
    Nginx高级配置-https功能
    Linux操作系统的压缩、解压缩工具介绍
    Nginx高级配置-压缩功能
    Nginx高级配置-自定义json格式日志
  • 原文地址:https://www.cnblogs.com/codedecision/p/11803154.html
Copyright © 2011-2022 走看看