记两个算法:一个纯暴力解决,超越了0.0%的用户:
public int tallestBillboard(int[] rods) {
int total = 0;
for (int i : rods) {
total += i;
}
return tallestBillboardAss(rods, 0, 0, 0, total, 0);
}
public int tallestBillboardAss(int[] rods, int left, int right, int i, int total, int re) {
if (i == rods.length && left == right) {
return left;
} else if (i == rods.length && left != right) {
return 0;
} else if (Math.abs(left - right) > total) {
return 0;
} else if (re > (left + right + total) / 2) {
return 0;
}
int b = tallestBillboardAss(rods, left + rods[i], right, i + 1, total - rods[i], re);
re = b > re ? b : re;
int c = tallestBillboardAss(rods, left, right + rods[i], i + 1, total - rods[i], re);
re = re > c ? re : c;
int a = tallestBillboardAss(rods, left, right, i + 1, total - rods[i], re);
return Math.max(re, a);
}
另一个算法较为优秀,采用的是动态规划方法:
public int tallestBillboard2(int[] rods) {
int len = rods.length;
int[][] dp = new int[len+1][5001];
for (int i = 0; i < len+1; i++) {
for (int j = 0; j < dp[0].length; j++) {
dp[i][j] = -5001;
}
}
int sum = 0;
dp[0][0] = 0;
for (int i = 1; i <= len; i++) {
sum += rods[i-1];
for (int j = 0; j <= sum; j++) {
dp[i][j] = Math.max(dp[i-1][j],dp[i][j]);
if (j + rods[i-1] <= sum) {
dp[i][j+rods[i-1]] = Math.max(dp[i-1][j], dp[i][j+rods[i-1]]);
}
dp[i][Math.abs(j-rods[i-1])] = Math.max(dp[i][Math.abs(j-rods[i-1])], dp[i-1][j] + Math.min(j,rods[i-1]));
}
}
return dp[len][0];
}