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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, b, n) for (int i = b; i < n; i++)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

const int INF = 1 << 29;
const double EPS = 1e-9;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};

int n, k;
int dp[11][2010]; // ジャンルiまででj冊売った時の最大の値段
vector<int> book[11];
int solve(int j, int i) { // 売った本がj冊で今ジャンルiを売る
  if (j == k)
    return 0;
  if (i > 10)
    return 0;

  if (dp[i][j] != -1)
    return dp[i][j];
  int res = 0;
  int sum = 0;
  res = solve(j, i + 1);
  int len = min((int)book[i].size(), k - j);
  for (int m = 0; m < len; m++) {
    sum += book[i][m];
    res = max(res, solve(j + m + 1, i + 1) + sum + m * (m + 1));
  }
  return dp[i][j] = res;
}
int main() {
  for (int i = 1; i <= 10; i++) {
    fill(dp[i], dp[i] + 2009, -1);
  }
  cin >> n >> k;
  map<int, int> ma;
  for (int i = 1; i <= n; i++) {
    int a, b;
    cin >> a >> b;
    book[b].push_back(a);
    ma[b] = 1;
  }
  int l = ma.size();
  for (int i = 0; i <= 10; i++) {
    sort(book[i].begin(), book[i].end(), greater<int>());
  }
  cout << solve(0, 1) << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, b, n) for (int i = b; i < n; i++)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

const int INF = 1 << 29;
const double EPS = 1e-9;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};

int n, k;
int dp[11][2010]; // ジャンルiまででj冊売った時の最大の値段
vector<int> book[11];
int solve(int j, int i) { // 売った本がj冊で今ジャンルiを売る
  if (j == k)
    return 0;
  if (i > 10)
    return 0;

  if (dp[i][j] != -1)
    return dp[j][i];
  int res = 0;
  int sum = 0;
  res = solve(j, i + 1);
  int len = min((int)book[i].size(), k - j);
  for (int m = 0; m < len; m++) {
    sum += book[i][m];
    res = max(res, solve(j + m + 1, i + 1) + sum + m * (m + 1));
  }
  return res;
}
int main() {
  for (int i = 1; i <= 10; i++) {
    fill(dp[i], dp[i] + 2009, -1);
  }
  cin >> n >> k;
  map<int, int> ma;
  for (int i = 1; i <= n; i++) {
    int a, b;
    cin >> a >> b;
    book[b].push_back(a);
    ma[b] = 1;
  }
  int l = ma.size();
  for (int i = 0; i <= 10; i++) {
    sort(book[i].begin(), book[i].end(), greater<int>());
  }
  cout << solve(0, 1) << endl;
  return 0;
}