poj 3111 賣珠寶問題 最大化平均值
阿新 • • 發佈:2018-08-04
clu clas sca pri include fin algo main using
題意:有N件分別價值v重量w的珠寶,希望保留k件使得 s=v的和/w的和最大
思路:找到貢獻最大的
- 設當前的s為mid(x)
- 那麽貢獻就是 v-w*x 排序 ,取前k個
bool operator<(const node& c) const
{
return v - x * w > c.v - x * c.w;
} - 如果前k的s>mid說明 mid太小 增下限
- 如果前k的s<mid說明 mid太大 減上限
解決問題的代碼:
#include <iostream> #include <stdio.h> #include <algorithm> #include<math.h> using namespace std; #define maxn 100000 double x; int n, k; struct node { int v, w; int id; bool operator<(const node& c) const { return v - x * w > c.v - x * c.w; } }no[maxn]; bool solve(double mid) { x = mid; sort(no, no + n); double v = 0, w = 0; for (int i = 0; i < k; i++) { v += no[i].v; w += no[i].w; } return v / w > mid; } int main() { double maxs = 0; scanf("%d%d", &n, &k); for (int i = 0; i < n; i++) { scanf("%d%d", &no[i].v, &no[i].w); no[i].id = i + 1; maxs = max(maxs, (double)no[i].v / no[i].w); } double lb = 0, ub = maxs; for (int i = 1; i < 50; i++) { double mid = (lb + ub) / 2; if (solve(mid)) lb = mid; else ub = mid; } int ids[maxn]; for (int i = 0; i < k; i++) { ids[i] = no[i].id; } sort(ids, ids + k); for (int i = 0; i < k; i++) printf("%d ", ids[i]); printf("\n"); return 0; }
poj 3111 賣珠寶問題 最大化平均值