HDU 4269 Buildings (贪心)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4296


题意:有n个砖块,每个砖块有两个属性wi和si,将所有的砖块依次叠放起来,每个砖块得到一个值ti=sigama(W)-si,其中W为在第i块砖上面的砖的总w值之和。要求求一种叠放次序,使得max(ti)最小。


一看就是一道贪心题。。可是方法怎么也想不到。。。

看了许多写给会的人看的题解。。还是不理解,还好找到一篇分析得很清晰优雅的,在这里分享一下。

思路:假设某一种叠放次序,对于第i,i+1两个砖块来说,他们的次序谁在上谁在下对i以前和i+1以后的都没有影响。设W为第i块上面的值:(t1、t2分别为上面、下面的ti值)


(1)第i块在上,则t1=W−si,t2=W+wi−si+1t1=W−si,t2=W+wi−si+1,此时最大值p=max(t1,t2)=max(W−si,W+wi−si+1)p=max(t1,t2)=max(W−si,W+wi−si+1)


(2)第i+1块在上,则t1=W−si+1,t2=W+wi+1−sit1=W−si+1,t2=W+wi+1−si,此时最大值q=max(t1,t2)=max(W−si+1,W+wi+1−si)q=max(t1,t2)=max(W−si+1,W+wi+1−si);


若p<qp<q,那么i在i+1上较优。此时有max(W−si,W+wi−si+1)<max(W−si+1,W+wi+1−si)max(W−si,W+wi−si+1)<max(W−si+1,W+wi+1−si),两边同时加上si+si+1−Wsi+si+1−W,即:


则max(si+1,wi+si)<max(si,wi+1+si+1)max(si+1,wi+si)<max(si,wi+1+si+1),所以只需:si+wi<si+1+wi+1si+wi<si+1+wi+1。所以只需按照si+wisi+wi升序排列,扫描一遍即可。


参考博客:http://www.cnblogs.com/jianglangcaijin/archive/2012/09/21/2696477.html


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
int n;
P a[100100];
bool cmp(P a, P b) {
	return a.first + a.second < b.first + b.second;
}
int main() {
	while(~scanf("%d", &n)) {
		for(int i = 1; i <= n; i++) scanf("%I64d %I64d", &a[i].first, &a[i].second);
		sort(a + 1, a + n + 1, cmp);
		ll sum = 0;
		ll ans = 0;
		for(int i = 1; i <= n; i++) {
			if(sum - a[i].second > ans) ans = sum - a[i].second;
			sum += a[i].first;
		}
		printf("%I64d\n", ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值