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)和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;
}