Problem p02618 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>

const int days = 365;
int c[26];
int t[days];
int s[days][26];

int getUndelta(int day) {
  // 前に何日分あるか
  int cnt1 = 0;
  for (int k = day - 1; k >= 0; --k) {
    if (t[k] != t[day])
      cnt1++;
    else
      break;
  }

  // 後に何日分あるか
  int cnt2 = 0;
  for (int k = day + 1; k < days; ++k) {
    if (t[k] != t[day])
      cnt2++;
    else
      break;
  }

  // 増加量
  int sum = (cnt2 + 1) * (cnt1 + 1);

  // 合計の削減量
  return s[day][t[day]] + sum * c[t[day]];
}

int getDelta(int day, int target) {
  // 前に何日分あるか
  int cnt1 = 0;
  for (int k = day - 1; k >= 0; --k) {
    if (t[k] != target)
      cnt1++;
    else
      break;
  }

  // 後に何日分あるか
  int cnt2 = 0;
  for (int k = day + 1; k < days; ++k) {
    if (t[k] != target)
      cnt2++;
    else
      break;
  }

  // 削減出来る量
  int sum = (cnt2 + 1) * (cnt1 + 1);

  // 合計の削減量
  return s[day][target] + sum * c[target];
}

void applo() {
  for (int i = 0; i < days; ++i) {
    // デメリットの計算
    int unDelta = getUndelta(i);

    // メリットの計算
    int maxDelta = 0;
    int maxT = 0;
    for (int f = 0; f < 26; ++f) {
      if (f == t[i])
        continue;

      // もともとの増える量
      int delta = getDelta(i, f);

      if (maxDelta == 0 || maxDelta < delta) {
        maxDelta = delta;
        maxT = f;
      }
    }

    if (maxDelta > unDelta) {
      t[i] = maxT;
    }
  }
}

void app(int day1, int day2) {
  int bt1 = t[day1];
  int bt2 = t[day2];
  int at1 = t[day1];
  int at2 = t[day2];

  int maxDelta = 0;
  for (int target1 = 0; target1 < 26; ++target1) {
    for (int target2 = 0; target2 < 26; ++target2) {
      t[day1] = bt1;
      int delta = -getUndelta(day1) + getDelta(day1, target1);
      t[day1] = target1;
      delta += -getUndelta(day2) + getDelta(day2, target2);

      if (maxDelta < delta) {
        maxDelta = delta;
        at1 = target1;
        at2 = target2;
      }
    }
  }
  t[day1] = at1;
  t[day2] = at2;
}

void bet(int day1, int day2, int day3) {
  int bt1 = t[day1];
  int bt2 = t[day2];
  int bt3 = t[day3];
  int at1 = t[day1];
  int at2 = t[day2];
  int at3 = t[day3];

  int maxDelta = 0;
  for (int target1 = 0; target1 < 26; ++target1) {
    for (int target2 = 0; target2 < 26; ++target2) {
      for (int target3 = 0; target3 < 26; ++target3) {
        t[day1] = bt1;
        t[day2] = bt2;
        int delta = -getUndelta(day1) + getDelta(day1, target1);
        t[day1] = target1;
        delta += -getUndelta(day2) + getDelta(day2, target2);
        t[day2] = target2;
        delta += -getUndelta(day3) + getDelta(day3, target3);

        if (maxDelta < delta) {
          maxDelta = delta;
          at1 = target1;
          at2 = target2;
          at2 = target3;
        }
      }
    }
  }
  t[day1] = at1;
  t[day2] = at2;
  t[day3] = at3;
}

void app2() {
  for (int day = 0; day < days - 1; ++day) {
    app(day, day + 1);
  }
}

int main() {
  int d;
  std::cin >> d;

  for (int i = 0; i < 26; ++i)
    std::cin >> c[i];

  for (int i = 0; i < days; ++i)
    for (int j = 0; j < 26; ++j)
      std::cin >> s[i][j];

  for (int i = 0; i < days; ++i) {
    std::cin >> t[i];
    t[i]--;
  }

  // 満足度の計算
  // int score = 0;
  for (int i = 0; i < days; ++i) {
    int maxDelta = 0;

    for (int f = 0; f < 26; ++f) {
      int delta = s[i][f];
      // score += s[i][t[i]];

      for (int j = 0; j < 26; ++j) {
        for (int k = i; k >= 0; --k) {
          if (t[k] != j)
            delta -= c[j];
        }
      }

      if (maxDelta == 0 || maxDelta < delta) {
        maxDelta = delta;
        t[i] = f;
      }
    }
  }

  // 初期最適化
  for (int se = 0; se < 5; ++se)
    app2();

  for (int j = 0; j < 6; j++) {
    // 初期最適化
    for (int se = 0; se < 1; ++se)
      app2();

    for (int i = 0; i < 12000; ++i) {
      int day1 = rand() % days;
      int day2 = rand() % days;

      if (day1 != day2 && std::abs(day1 - day2) < 30)
        app(day1, day2);
    }
  }
  // 初期最適化
  for (int se = 0; se < 5; ++se)
    app2();

  for (int i = 0; i < days; ++i)
    std::cout << t[i] + 1 << std::endl;
}

Error: TLE

Fixed submission:

#include <iostream>

const int days = 365;
int c[26];
int t[days];
int s[days][26];

int getUndelta(int day) {
  // 前に何日分あるか
  int cnt1 = 0;
  for (int k = day - 1; k >= 0; --k) {
    if (t[k] != t[day])
      cnt1++;
    else
      break;
  }

  // 後に何日分あるか
  int cnt2 = 0;
  for (int k = day + 1; k < days; ++k) {
    if (t[k] != t[day])
      cnt2++;
    else
      break;
  }

  // 増加量
  int sum = (cnt2 + 1) * (cnt1 + 1);

  // 合計の削減量
  return s[day][t[day]] + sum * c[t[day]];
}

int getDelta(int day, int target) {
  // 前に何日分あるか
  int cnt1 = 0;
  for (int k = day - 1; k >= 0; --k) {
    if (t[k] != target)
      cnt1++;
    else
      break;
  }

  // 後に何日分あるか
  int cnt2 = 0;
  for (int k = day + 1; k < days; ++k) {
    if (t[k] != target)
      cnt2++;
    else
      break;
  }

  // 削減出来る量
  int sum = (cnt2 + 1) * (cnt1 + 1);

  // 合計の削減量
  return s[day][target] + sum * c[target];
}

void applo() {
  for (int i = 0; i < days; ++i) {
    // デメリットの計算
    int unDelta = getUndelta(i);

    // メリットの計算
    int maxDelta = 0;
    int maxT = 0;
    for (int f = 0; f < 26; ++f) {
      if (f == t[i])
        continue;

      // もともとの増える量
      int delta = getDelta(i, f);

      if (maxDelta == 0 || maxDelta < delta) {
        maxDelta = delta;
        maxT = f;
      }
    }

    if (maxDelta > unDelta) {
      t[i] = maxT;
    }
  }
}

void app(int day1, int day2) {
  int bt1 = t[day1];
  int bt2 = t[day2];
  int at1 = t[day1];
  int at2 = t[day2];

  int maxDelta = 0;
  for (int target1 = 0; target1 < 26; ++target1) {
    for (int target2 = 0; target2 < 26; ++target2) {
      t[day1] = bt1;
      int delta = -getUndelta(day1) + getDelta(day1, target1);
      t[day1] = target1;
      delta += -getUndelta(day2) + getDelta(day2, target2);

      if (maxDelta < delta) {
        maxDelta = delta;
        at1 = target1;
        at2 = target2;
      }
    }
  }
  t[day1] = at1;
  t[day2] = at2;
}

void bet(int day1, int day2, int day3) {
  int bt1 = t[day1];
  int bt2 = t[day2];
  int bt3 = t[day3];
  int at1 = t[day1];
  int at2 = t[day2];
  int at3 = t[day3];

  int maxDelta = 0;
  for (int target1 = 0; target1 < 26; ++target1) {
    for (int target2 = 0; target2 < 26; ++target2) {
      for (int target3 = 0; target3 < 26; ++target3) {
        t[day1] = bt1;
        t[day2] = bt2;
        int delta = -getUndelta(day1) + getDelta(day1, target1);
        t[day1] = target1;
        delta += -getUndelta(day2) + getDelta(day2, target2);
        t[day2] = target2;
        delta += -getUndelta(day3) + getDelta(day3, target3);

        if (maxDelta < delta) {
          maxDelta = delta;
          at1 = target1;
          at2 = target2;
          at2 = target3;
        }
      }
    }
  }
  t[day1] = at1;
  t[day2] = at2;
  t[day3] = at3;
}

void app2() {
  for (int day = 0; day < days - 1; ++day) {
    app(day, day + 1);
  }
}

int main() {
  int d;
  std::cin >> d;

  for (int i = 0; i < 26; ++i)
    std::cin >> c[i];

  for (int i = 0; i < days; ++i)
    for (int j = 0; j < 26; ++j)
      std::cin >> s[i][j];

  for (int i = 0; i < days; ++i) {
    std::cin >> t[i];
    t[i]--;
  }

  // 満足度の計算
  // int score = 0;
  for (int i = 0; i < days; ++i) {
    int maxDelta = 0;

    for (int f = 0; f < 26; ++f) {
      int delta = s[i][f];
      // score += s[i][t[i]];

      for (int j = 0; j < 26; ++j) {
        for (int k = i; k >= 0; --k) {
          if (t[k] != j)
            delta -= c[j];
        }
      }

      if (maxDelta == 0 || maxDelta < delta) {
        maxDelta = delta;
        t[i] = f;
      }
    }
  }

  // 初期最適化
  for (int se = 0; se < 10; ++se)
    app2();

  for (int j = 0; j < 6; j++) {
    // 初期最適化
    for (int se = 0; se < 1; ++se)
      app2();

    for (int i = 0; i < 12000; ++i) {
      int day1 = rand() % days;
      int day2 = rand() % days;

      if (day1 != day2 && std::abs(day1 - day2) < 30)
        app(day1, day2);
    }
  }
  // 初期最適化
  for (int se = 0; se < 10; ++se)
    app2();

  for (int i = 0; i < days; ++i)
    std::cout << t[i] + 1 << std::endl;
}