LeetCode Solutions

956. Tallest Billboard

Time: $O(n \cdot \texttt{sum})$, where $\texttt{sum} = \Sigma |\texttt{rods[i]}|$

Space: $O(n \cdot \texttt{sum})$

			

class Solution {
 public:
  int tallestBillboard(vector<int>& rods) {
    const int n = rods.size();
    const int sum = accumulate(begin(rods), end(rods), 0);
    // dp[i][j] := max min-height of using rods[0..i) to pile two piles that
    // Have height difference j
    vector<vector<int>> dp(n + 1, vector<int>(sum + 1, -1));
    dp[0][0] = 0;

    for (int i = 1; i <= n; ++i) {
      const int h = rods[i - 1];
      for (int j = 0; j <= sum - h; ++j) {
        if (dp[i - 1][j] < 0)
          continue;
        // don't use rods[i - 1]
        dp[i][j] = max(dp[i][j], dp[i - 1][j]);
        // Put on the taller pile
        dp[i][j + h] = max(dp[i][j + h], dp[i - 1][j]);
        // Put on the shorter pile
        dp[i][abs(j - h)] = max(dp[i][abs(j - h)], dp[i - 1][j] + min(j, h));
      }
    }

    return dp[n][0];
  }
};
			

class Solution {
  public int tallestBillboard(int[] rods) {
    final int n = rods.length;
    final int sum = Arrays.stream(rods).sum();
    // dp[i][j] := max min-height of using rods[0..i) to pile two piles that
    // Have height difference j
    int[][] dp = new int[n + 1][sum + 1];
    Arrays.stream(dp).forEach(row -> Arrays.fill(row, -1));
    dp[0][0] = 0;

    for (int i = 1; i <= n; ++i) {
      final int h = rods[i - 1];
      for (int j = 0; j <= sum - h; ++j) {
        if (dp[i - 1][j] < 0)
          continue;
        // don't use rods[i - 1]
        dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);
        // Put on the taller pile
        dp[i][j + h] = Math.max(dp[i][j + h], dp[i - 1][j]);
        // Put on the shorter pile
        dp[i][Math.abs(j - h)] = Math.max(dp[i][Math.abs(j - h)], dp[i - 1][j] + Math.min(j, h));
      }
    }

    return dp[n][0];
  }
}
			

class Solution {
 public:
  int tallestBillboard(vector<int>& rods) {
    const int sum = accumulate(begin(rods), end(rods), 0);
    // dp[i] := max min-height of using rods so far to pile two piles that have
    // Height difference i
    vector<int> dp(sum + 1, -1);
    dp[0] = 0;

    for (const int h : rods) {
      vector<int> prev(dp);
      for (int i = 0; i <= sum - h; ++i) {
        if (prev[i] < 0)
          continue;
        // don't use this rod
        dp[i] = max(dp[i], prev[i]);
        // Put on the taller pile
        dp[i + h] = max(dp[i + h], prev[i]);
        // Put on the shorter pile
        dp[abs(i - h)] = max(dp[abs(i - h)], prev[i] + min(i, h));
      }
    }

    return dp[0];
  }
};