четверг, 28 октября 2010 г.

Наибольшая общая подпоследовательность

По идее можно решать за O(nlogn), но здесь за O(n^2) простой динамикой:
#include <vector>
#include <iostream>
#include <algorithm>

using std::vector;
using std::cin;
using std::cout;
using std::max_element;

int countLongestCommonSubsequenceLength(const vector<int> &first_sequence,
                                        const vector<int> &second_sequence) {
  vector< vector<int> > common_prefix_length(first_sequence.size() +
    1, vector<int>(second_sequence.size() + 1, 0));
  for (size_t first_number = 1;
       first_number <= first_sequence.size();
       ++first_number) {
    for (size_t second_number = 1;
         second_number <= second_sequence.size();
         ++second_number) {
      if (first_sequence[first_number - 1] ==
          second_sequence[second_number - 1]) {
        common_prefix_length[first_number][second_number] =
          common_prefix_length[first_number - 1][second_number - 1] + 1;
      } else if (common_prefix_length[first_number - 1][second_number] >=
          common_prefix_length[first_number][second_number - 1]) {
        common_prefix_length[first_number][second_number] =
          common_prefix_length[first_number - 1][second_number];
      } else {
        common_prefix_length[first_number][second_number] =
          common_prefix_length[first_number][second_number - 1];
      }
    }
  }
  return common_prefix_length.back().back();
}

void readSequence(vector<int> *sequence) {
  int length, tmp_int;
  cin >> length;
  for (int element_number = 0; element_number < length; ++element_number) {
    cin >> tmp_int;
    sequence->push_back(tmp_int);
  }
}

int main() {
  vector<int> first_sequence, second_sequence;
  readSequence(&first_sequence);
  readSequence(&second_sequence);
  cout << countLongestCommonSubsequenceLength(first_sequence, second_sequence)
       << std::endl;
  return 0;
}

Комментариев нет:

Отправить комментарий