JAVA程序设计:最高的广告牌(LeetCode:956)

你正在安装一个广告牌,并希望它高度最大。这块广告牌将有两个钢制支架,两边各一个。每个钢支架的高度必须相等。

你有一堆可以焊接在一起的钢筋 rods。举个例子,如果钢筋的长度为 1、2 和 3,则可以将它们焊接在一起形成长度为 6 的支架。

返回广告牌的最大可能安装高度。如果没法安装广告牌,请返回 0。

 

示例 1:

输入:[1,2,3,6]
输出:6
解释:我们有两个不相交的子集 {1,2,3} 和 {6},它们具有相同的和 sum = 6。
示例 2:

输入:[1,2,3,4,5,6]
输出:10
解释:我们有两个不相交的子集 {2,3,5} 和 {4,6},它们具有相同的和 sum = 10。
示例 3:

输入:[1,2]
输出:0
解释:没法安装广告牌,所以返回 0。
 

提示:

0 <= rods.length <= 20
1 <= rods[i] <= 1000
钢筋的长度总和最多为 5000

思路:一个比较直观的方法是折半搜索,我们可以将原数组分成两部分分别进行枚举,其中每个元素有三种状态(第一个广告牌取,第二个广告牌取,两个都不取),复杂度只有O(3^(20/2))。鉴于这种方法比较简单,我这里不再赘述,我更倾向于放出复杂度更优的代码。

我们考虑动态规划,定义dp[i][j]表示前i个钢筋使得两个广告牌高度差为j的最大和,而我们最终要找的就是dp[n][0]/2的值。

class Solution {
    public int tallestBillboard(int[] rods) {
    	
    	int sum=0;
    	int n=rods.length;

    	for(int i=0;i<rods.length;i++)
    		sum+=rods[i];
    	
    	int[][] dp=new int[n+1][2*sum+1];	
    	
    	for(int i=1;i<=n;i++)
    		for(int j=0;j<=sum;j++) {
    			if(dp[i-1][j]<j)
    				continue;
    			int val=j+rods[i-1];
    			dp[i][val]=Math.max(dp[i][val], Math.max(dp[i-1][val], dp[i-1][j]+rods[i-1]));
    			val=Math.abs(j-rods[i-1]);
    			dp[i][val]=Math.max(dp[i][val], Math.max(dp[i-1][val], dp[i-1][j]+rods[i-1]));
    			dp[i][j]=Math.max(dp[i][j], dp[i-1][j]);
    		}
    	
    	return dp[n][0]/2;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值