Между двумя массивами

Условие задачи

Условие

Даны две неубывающих последовательности и длины . Все элементы массива .

Найдите количество таких неубывающих последовательностей из целых чисел , таких что .

По простому модулю .

Решение

Решение

  1. Двумерное — количество последовательностей длины , если для первых выполняется , и на позицию позицию поставили число .
  2. для — первый член последовательности .
  3. Считаем двумя вложеными циклами — for (int i = 1; i < n; i++) for (int x = 0; x <= 3000; x++)

Новое состояние :

  • . (так как по условию ) Если .
  • Иначе , так как число просто не может стоять на позиции .
  1. Ответ — .

Такое решение работает за ( по условию задачи одинаковые размерности) — TL. Давайте немного соптимизируем. Точнее напишем немного умнее.

  1. Можно хранить только два слоя, так как зависит только от значений => так красивее писать, и меньше памяти.
  2. Сумма для вычисления немного отличается от , а именно на значение .

Вау??? Если честно я офигел от того, когда вспомнил такую задачу. Это просто замечательная задача. Два способа позволяют написать такой лаконичный код всего с одним измерением:

void solve() {
  int n;
  cin >> n;
  vector<int> a(n), b(n);
  for (int i = 0; i < n; i++) cin >> a[i];
  for (int i = 0; i < n; i++) cin >> b[i];

  vector<int> dp(3000 + 7);
  for (int i = a[0]; i <= b[0]; i++) dp[i] = 1;

  for (int i = 1; i < n; i++) {
    int sum = 0;
    for (int ci = 0; ci < dp.size(); ci++) {
      sum = add(sum, dp[ci]);
      if (a[i] <= ci && ci <= b[i])
        dp[ci] = sum;
      else
        dp[ci] = 0;
    }
  }
  int ans = 0;
  for (auto& x : dp) {
    ans = add(ans, x);
  }
  cout << ans;
}