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

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int, int> pii;
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPR(i, n) for (int i = 1; i < n; ++i)

#define DEBUG(x) cout << #x << ": " << x << endl
#define DEBUG_VEC(v)                                                           \\
  REP(i, v.size()) cout << #v << "[" << i << "]: " << v[i] << endl
#define ALL(a) (a).begin(), (a).end()

int N, M;
vector<vector<pii>> pots(300);

double dfs(vector<int> used, int rest) {
  // used[n] = n's pot's upperbound
  // rest = rest of water
  double result = 0.0;

  REP(i, N) {
    int before_s = 1e9;
    int ui = used[i];
    double i_result = 0.0;
    int now_rest = rest;
    while (pots[i].size() > ui) {
      int pot_s = pots[i][ui].first;
      int pot_h = pots[i][ui].second;
      if (pot_s > before_s) {
        vi next_used = used;
        next_used[i] = ui;
        result = max(result, i_result + dfs(next_used, now_rest));
        break;
      }
      if (pot_s * pot_h >= now_rest) {
        result = max(result, i_result + (double)now_rest / (double)pot_s);
        break;
      }
      i_result += pot_h;
      now_rest -= pot_s * pot_h;
      before_s = pot_s;
      ++ui;
      if (pots[i].size() == ui) {
        vi next_used = used;
        next_used[i] = ui;
        result = max(result, i_result + dfs(next_used, now_rest));
        break;
      }
    }
    result = max(result, i_result);
  }
  return result;
}

double solve() {
  cin >> N >> M;
  int K = 0;
  REP(i, N) {
    int k;
    cin >> k;
    K = max(k, K);
    REP(j, k) {
      int S, H;
      cin >> S >> H;
      pots[i].push_back(make_pair(S, H));
    }
  }
  // vi used(N);
  // REP(i,N)used[i]=0;
  // return dfs(used,M);
  double dp[N][K + 1][M + 1];
  REP(i, N) REP(j, K + 1) REP(k, M + 1) dp[i][j][k] = 0.0;
  for (int i = N - 1; i >= 0; --i) {
    vector<pii> pot = pots[i];
    int pot_k = pot.size();
    for (int k = K; k >= 0; --k) {
      if (k > pot_k)
        continue;
      int pot_s = pot[k].first;
      int pot_h = pot[k].second;
      for (int m = 0; m <= M; ++m) {
        if (m == 0)
          continue;
        if (pot_s * pot_h >= m)
          dp[i][k][m] = (double)m / (double)pot_s;
        else
          dp[i][k][m] = dp[i][k + 1][m - pot_s * pot_h] + pot_h;
      }
    }
  }
  // REP(m,M+1){
  //   cout << "M=" << m << endl;
  //   REP(i,N){
  //     REP(j,K+1){
  //       cout << dp[i][j][m] << " ";
  //     }
  //     cout << endl;
  //   }
  // }
  double result = 0.0;
  REPR(i, N) {
    int k = 0;
    REP(_m, M + 1) {
      int m = M - _m;
      REP(mm, m + 1) {
        if (dp[i][k][m] < dp[i][k][mm] + dp[i - 1][k][m - mm]) {
          dp[i][k][m] = dp[i][k][mm] + dp[i - 1][k][m - mm];
        }
        // dp[i][k][m] = max(dp[i][k][m], dp[i][k][mm]+dp[i-1][k][m-mm]);
      }
    }
  }
  return dp[N - 1][0][M];
}

int main() {
  cout.precision(20);
  cout << fixed << solve() << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int, int> pii;
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPR(i, n) for (int i = 1; i < n; ++i)

#define DEBUG(x) cout << #x << ": " << x << endl
#define DEBUG_VEC(v)                                                           \\
  REP(i, v.size()) cout << #v << "[" << i << "]: " << v[i] << endl
#define ALL(a) (a).begin(), (a).end()

int N, M;
vector<vector<pii>> pots(300);

double dfs(vector<int> used, int rest) {
  // used[n] = n's pot's upperbound
  // rest = rest of water
  double result = 0.0;

  REP(i, N) {
    int before_s = 1e9;
    int ui = used[i];
    double i_result = 0.0;
    int now_rest = rest;
    while (pots[i].size() > ui) {
      int pot_s = pots[i][ui].first;
      int pot_h = pots[i][ui].second;
      if (pot_s > before_s) {
        vi next_used = used;
        next_used[i] = ui;
        result = max(result, i_result + dfs(next_used, now_rest));
        break;
      }
      if (pot_s * pot_h >= now_rest) {
        result = max(result, i_result + (double)now_rest / (double)pot_s);
        break;
      }
      i_result += pot_h;
      now_rest -= pot_s * pot_h;
      before_s = pot_s;
      ++ui;
      if (pots[i].size() == ui) {
        vi next_used = used;
        next_used[i] = ui;
        result = max(result, i_result + dfs(next_used, now_rest));
        break;
      }
    }
    result = max(result, i_result);
  }
  return result;
}

double solve() {
  cin >> N >> M;
  REP(i, N) {
    int K;
    cin >> K;
    REP(j, K) {
      int S, H;
      cin >> S >> H;
      pots[i].push_back(make_pair(S, H));
    }
  }
  vi used(N);
  REP(i, N) used[i] = 0;
  return dfs(used, M);
}

int main() {
  cout.precision(20);
  cout << fixed << solve() << endl;
  return 0;
}