UVa 1346 Songs (貪心好題)
阿新 • • 發佈:2019-02-13
思路:直接看這個和式,記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; }