POJ3045 Cow Acrobats(贪心)

题目链接:http://poj.org/problem?id=3045

有n头奶牛叠罗汉,其中第i头奶牛的重量为wi,力量为si,每头奶牛有一个难受值di,等于他上面所有奶牛的重量和减去他的力量,现在找出一种方案,使得这n头奶牛中最大的难受值尽量小

这里有一个猜想,把wi+si作为关键字排序,大的排在后面,反正我是没有想出来,在这里简单证明一下

设i,j是相邻的奶牛,而且wi+si>wj+sj,求证:i放在下面比j放在下面更优:

则排列情况为:

.....
.....
     j
     i
.....
或者

......
......
     i'
     j'
......

由于i,j的位置关系对其他奶牛的难受值无关,所以我们只需要单独考虑i,j的难受值,设C为i,j上面所有奶牛的重量和

那么有di = C + wj - si  ①   dj = C - sj           ②

    di' = C - si        ③   dj' = C + wi - sj   ④

因为wi+si>wj+sj 所以wi - sj > wj - si 所以④>①

显然①>③,④>②成立,因此这4个难受值当中dj'是最大的,而dj'表示的是j放在i下面,因此我们只需要把i,j交换,让i放在下面,就比j放在下面更优

那么这里的i,j是相邻的两头奶牛,无法说明整体的问题,怎么办呢?

我们可以把这个混乱的顺序当做冒泡排序的过程,遇到不合法的情况交换一下就行了,因此我们只需要证明相邻两头奶牛在什么情况下有最优解,而不需要证明两头奶牛不相邻时候的情况。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define MAXN 50005
using namespace std;
struct T
{
	int w,l;
}a[MAXN];
bool cmp(T x,T y)
{
	return x.w+x.l<y.w+y.l;
}
int n;
int sum,ans = -123456789;
int main()
{
	scanf("%d",&n);
	for(int i = 1; i <= n; i++)
	{	
		scanf("%d%d",&a[i].w,&a[i].l);
	}
	sort(a+1,a+n+1,cmp);
	for(int i = 1; i <= n; i++)
	{
		ans = max(ans,sum-a[i].l);
		sum += a[i].w;
	}
	printf("%d\n",ans);
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值