algorithm - 矩阵中要删除的最小列以使其按行字典顺序排序

标签 algorithm dynamic-programming

我正在尝试解决这个招聘竞赛问题(现已结束)

Lexicographic Rows

You are given a matrix of characters. In one operation you can remove a column of the matrix. You can perform as many operations as you want. Your task is to make the final matrix interesting i.e. the string formed by the characters of row is lexicographically smaller or equal to the string formed by the characters of the row. You need to use minimum number of operations possible. An empty matrix is always a interesting matrix.

Input

The first line contains two integers and . The next lines contain letters each.

Output

In the output, you need to print the minimum number of operations to make the matrix interesting.

Constraints

There are only lowercase English alphabets as characters in the input.

Sample Input

3 3

cfg

agk

dlm

Sample Output

1

Explanation

Delete the first column to make the matrix interesting.

我非常确信这是一个 DP 问题。不过,我很难找到最佳子问题。我设法只通过了几个测试用例

我将 dp[i][j] 定义为要删除的最小列数,以获得有趣的矩阵。

对于每个字符 input[i][j] 都有两种可能性。

  1. 如果前一个条目在字典顺序上是有效的,我们可以采用 dp[i][j - 1] 并且当前输入不会改变任何东西。
  2. 否则我们检查 input[i -1][j]input[i][j] 是否按照我们考虑的正确顺序 dp[i][j - 1] 否则这一列也是无效的,所以我们将 1 添加到 dp[i][j-1]<

我的解决方案。代码

int n, m;
cin >> n >> m;
vector<string> input(n);
for (int i = 0; i < n; ++i) {
    string temp = "";
    for (int j = 0; j < m; ++j) {
        char c;
        cin >> c;
        temp = temp + c;
    }
    input[i] = temp;
}

vector<vector<int> > dp(n, vector<int>(m, 0));

for (int i = 1; i < n; ++i) {
    for (int j = 1; j < m; ++j) {
        //Left is valid
        if (input[i - 1][j - 1] < input[i][j - 1]) {
            dp[i][j] = dp[i][j - 1];
        }
        else {
            //Current is valid
            if (input[i - 1][j] <= input[i][j]) {
                dp[i][j] = dp[i][j - 1];
            }
            else {
                dp[i][j] = dp[i][j - 1] + 1;
            }
        }
    }
}
cout << dp[n - 1][m - 1] << endl;

最佳答案

我们可以从左到右遍历列,选择那些不会使当前矩阵变得无趣的列。如果实现得当,这将花费与输入大小成线性关系的时间。

支持该算法的关键事实是,给定两个有趣的列子集,我们可以将其中一个缺失的第一列添加到另一个,而不会使它变得无趣。

关于algorithm - 矩阵中要删除的最小列以使其按行字典顺序排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55325386/

相关文章:

algorithm - 帮助我找到我在 Haskell 中对 Project Euler #12 的解决方案的问题

ruby - Ruby 中按日期(按距离)聚类

arrays - 给定一个数组,打印所有可能的连续子序列,其总和可被给定数字 x 整除

c++ - Blueberry (SPOJ) - 超出动态规划时间限制

algorithm - 最有效的座位安排

algorithm - 树木切边

arrays - 有序数组中重复的数字

java - 计算代表 n 分的可能组合的数量

当没有数据类型可以容纳完整数字时,将十六进制转换为十进制

algorithm - 最大权重增加子序列