卖宝救夫:Demy要卖珠宝,n件分别价值vi 重 wi,她希望保留k件使得
最大。
3.1不光是查找值!“二分搜索”
最大化平均值
晚上A一题睡的香,这题跟POJ 2976 Dropping tests一个原理,注意结束条件的选取,2的50次方已经是相当大的数了,完全可以覆盖解空间。
#ifndef ONLINE_JUDGE #pragma warning(disable : 4996) #endif #include <iostream> #include <algorithm> #include <iterator> using namespace std; #define MAX_N 100000 + 16 int n, k; double s; struct Jewel { int v, w; int id; bool operator < (const Jewel& other) const { return v - s * w > other.v - s * other.w; } }; Jewel jewel[MAX_N]; int ids[MAX_N]; bool C(double mid) { s = mid; sort(jewel, jewel + n); double total_v = 0, total_w = 0; for (int i = 0; i < k; ++i) // 前k个数计算s { total_v += jewel[i].v; total_w += jewel[i].w; } return total_v / total_w > mid; } ///////////////////////////SubMain////////////////////////////////// int main(int argc, char *argv[]) { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif cin >> n >> k; double max_s = 0; for (int i = 0; i < n; ++i) { cin >> jewel[i].v >> jewel[i].w; jewel[i].id = i + 1; max_s = max(max_s, (double)jewel[i].v / jewel[i].w); } double lb = 0; double ub = max_s; for (int i = 0; i < 50; ++i) { double mid = (lb + ub) / 2; if (C(mid)) { lb = mid; // 行,说明mid太小 } else { ub = mid; // 不行,说明mid太大 } } for (int i = 0; i < k; ++i) { ids[i] = jewel[i].id; } sort(ids, ids + k); copy(ids, ids + k, ostream_iterator<int>(cout, " ")); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); system("out.txt"); #endif return 0; } ///////////////////////////End Sub//////////////////////////////////
12824357 | hankcs | 3111 | Accepted | 1816K | 5797MS | C++ | 1554B | 2014-04-30 23:41:52 |
我认为这五秒钟是IO的错,不是算法的问题
楼主,这道题的精度要求有多高啊!我WA了好多次