You are installing a billboard and want it to have the largest height. The billboard will have two steel supports, one on each side. Each steel support must be an equal height.
You have a collection of rods
which can be welded together. For example, if you have rods of lengths 1, 2, and 3, you can weld them together to make a support of length 6.
Return the largest possible height of your billboard installation. If you cannot support the billboard, return 0.
Example 1:
Input: [1,2,3,6] Output: 6 Explanation: We have two disjoint subsets {1,2,3} and {6}, which have the same sum = 6.
Example 2:
Input: [1,2,3,4,5,6] Output: 10 Explanation: We have two disjoint subsets {2,3,5} and {4,6}, which have the same sum = 10.
Example 3:
Input: [1,2] Output: 0 Explanation: The billboard cannot be supported, so we return 0.
Note:
0 <= rods.length <= 20
1 <= rods[i] <= 1000
The sum of rods is at most 5000.
思路:暴力BFS TLE;改用dp,dp[i][j]=True,表示(I,J)2部分可以分别得到i,j,具体求解过程就是对于没来一个数,就更新一遍dp[i][j]数组,但是复杂度太大了。
仔细想想,每来rods数组中一个数,是用来改变(I,J)之间差值,所以其实只需要一维数组就够了,dp[i]表示(I,J)差值为i时,(I,J)中 小的/大的 那个数最大是多少
But don't forget, we don't care every state. We only care about the best state.
For example, if we have dp[i][j] = True and dp[i+k][j+k] = True. Do we still care dp[i][j] ? No!
So the state description can be simplized to dp[dx] = len, which means we can realize the state (len, len+dx).
class Solution(object):
def tallestBillboard(self, rods):
"""
:type rods: List[int]
:rtype: int
"""
if not rods: return 0
su = sum(rods)
dp = [-1]*(su+1)
dp[0] = 0
dp2=list(dp)
for i in rods:
for j in range(su+1):
if dp[j]==-1: continue
# add to larger
if j+i<=su:
dp2[j+i]=max(dp2[j+i], dp[j])
# add to smaller
if j>=i:
dp2[j-i]=max(dp2[j-i], dp[j]+i)
else:
dp2[i-j]=max(dp2[i-j], dp[j]+j)
dp=list(dp2)
return dp[0]
s=Solution()
print(s.tallestBillboard([61,45,43,54,40,53,55,47,51,59,42]))
print(s.tallestBillboard([2,4,8,16]))
print(s.tallestBillboard([1,2,3,6]))
#print(s.tallestBillboard([1,2,3,4,5,6]))
#print(s.tallestBillboard([1,2]))