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

Posted

技术标签:

【中文标题】矩阵中要删除的最少列以使其按行按字典顺序排序【英文标题】: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],有两种可能性。

    如果前一个条目在字典上是有效的,我们可以采用 dp[i][j - 1] 并且当前输入不会改变任何内容。 否则我们检查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 个测试用例。 【参考方案1】:

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

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

【讨论】:

以上是关于矩阵中要删除的最少列以使其按行按字典顺序排序的主要内容,如果未能解决你的问题,请参考以下文章

R语言创建使用矩阵(按行按列填充,矩阵命名,矩阵下标使用,数据框转换为矩阵)

R语言创建使用矩阵(按行按列填充,矩阵命名,矩阵下标使用,数据框转换为矩阵)

Nvivo 10 如何调整Node顺序?使其按自己想要的顺序排列

使用其构造函数初始化 OrderedDict 以使其保留初始数据顺序的正确方法?

在 C# Windows 窗体中对字典进行排序[重复]

如何隐藏 DefaultTableModel 中的特定列以使其在表中显示?