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];
}
};