【问题标题】:minimum columns to be deleted in a matrix to make it row-wise lexicographically sorted矩阵中要删除的最少列以使其按行按字典顺序排序
【发布时间】:2019-03-24 15:29:50
【问题描述】:

我试图解决这个招聘竞赛问题(现已关闭)

字典行

给你一个字符矩阵。在一项操作中,您可以删除 矩阵的一列。您可以执行尽可能多的操作 想。你的任务是使最终的矩阵变得有趣,即 由 row 的字符组成的字符串在字典上更小 或等于由该行的字符组成的字符串。你需要 尽可能使用最少的操作数。一个空矩阵是 总是一个有趣的矩阵。

输入

第一行包含两个整数和。下一行包含 每个字母。

输出

在输出中,需要打印最少的操作数 让矩阵变得有趣。

约束

输入中只有小写英文字母作为字符。

示例输入

3 3

cfg

agk

dlm

样本输出

1

说明

删除第一列以使矩阵变得有趣。

我很确定这是一个 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;

【问题讨论】:

  • 测试提交的链接是什么?输入矩阵的大小有什么限制?
  • 你不能测试它比赛结束了
  • 你是如何解决第一个问题的(LCS Again)?即使我尝试优化空间,但我只通过了 3 个测试用例。

标签: algorithm dynamic-programming


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多