минимальное количество столбцов, которые нужно удалить в матрице, чтобы сделать ее построчно лексикографически отсортированной - PullRequest
1 голос
/ 24 марта 2019

Я пытался решить эту проблему конкурса найма (сейчас закрыт) * ​​1001 *

Лексикографические строки

Вам дана матрица символов. В одну операцию вы можете удалить столбец матрицы. Вы можете выполнить столько операций, сколько вам хочу. Ваша задача - сделать итоговую матрицу интересной, т.е. строка, образованная символами строки, лексикографически меньше или равно строке, образованной символами строки. Тебе нужно использовать минимально возможное количество операций. Пустая матрица всегда интересная матрица.

Input

Первая строка содержит два целых числа и. Следующие строки содержат буквы каждая.

выход

В выводе вам нужно вывести минимальное количество операций для сделать матрицу интересной.

Препятствия

В качестве символов на входе используются только строчные буквы английского алфавита.

Пример ввода

3 3

CFG

АГК

ДЛМ

Пример вывода

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;

1 Ответ

1 голос
/ 25 марта 2019

Мы можем перебирать столбцы слева направо, выбирая те, чье включение не сделает текущую матрицу неинтересной.При правильной реализации это займет время, линейное по размеру входных данных.

Ключевым фактом, поддерживающим этот алгоритм, является то, что, учитывая два интересных подмножества столбцов, мы можем добавить первый отсутствующий столбец из одного в другой безделая это неинтересным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...