UVa 1346 Songs (贪心好题)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=4092


思路:直接看这个和式,记A(i)=f(i)Σl(j) (1<=j<=i),则sum=ΣA(i)(别被下标迷惑了,s(i)完全可以用i代替)。

设sum已经达到最小,

记sum1 = A(i)+A(i+1) = (f(i)+f(i+1))*(l(1)+...+l(i-1)) + f(i)*l(i) f(i+1)*l(i) + f(i+1)*l(i+1)

交换f(i)和f(i+1),交换l(i)和l(i+1),得sum2= (f(i)+f(i+1))*(l(1)+...+l(i-1)) + f(i)*l(i) f(i)*l(i+1) + f(i+1)*l(i+1)

因为sum最小,必有sum1<=sum2,故f(i+1)*l(i)<=f(i)*l(i+1)

(也可以这么理解,频率越大的,长度越短的,即f(i)/l(i)越大的,位置越靠前)


完整代码:

/*0.032s*/

#include<bits/stdc++.h>
using namespace std;

struct node
{
	int id;
	double l, f;
	bool operator < (const node& a) const
	{
		return a.f * l < f * a.l;
	}
} a[65540];

int main()
{
	int n, i, s;
	while (~scanf("%d", &n))
	{
		for (i = 1; i <= n; ++i)
			scanf("%d%lf%lf", &a[i].id, &a[i].l, &a[i].f);
		scanf("%d", &s);
		nth_element(a + 1, a + s, a + n + 1);
		printf("%d\n", a[s].id);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值