1. 程式人生 > >poj 3111 賣珠寶問題 最大化平均值

poj 3111 賣珠寶問題 最大化平均值

clu clas sca pri include fin algo main using

題意:有N件分別價值v重量w的珠寶,希望保留k件使得 s=v的和/w的和最大

思路:找到貢獻最大的

  1. 設當前的s為mid(x)
  2. 那麽貢獻就是 v-w*x 排序 ,取前k個

    bool operator<(const node& c) const
    {
    return v - x * w > c.v - x * c.w;
    }

  3. 如果前k的s>mid說明 mid太小 增下限
  4. 如果前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 賣珠寶問題 最大化平均值