[POJ 3111]ベストK

01得点は、バイナリ回答のクラスに共通の質問を計画しています

問題の説明:

Nあなたに最大で割っ要件、V及びWを取り出すための要素のVI、WI、Kを与え、

解像度:

[I] wは、我々は[I] /シグマvのX =シグマの最大値を算出したと;

そこ

> = X([I]における)シグマ(V [I])/シグマ - >シグマ(V [I] - X *で[I])> = 0

決定されたデータの場合には、この式が単調であるので、我々は、この二分法値xを解くことを検討することができます

コード:POJ3111 Kベスト

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>

const int maxn = 100010;
const int INF = 0x7fffffff;

int v[maxn], w[maxn];

struct Node
{
    double val;
    int id;
    bool operator<(const Node &a) const
    {
        return val > a.val;
    }
} f[maxn];

int ans[maxn];

int n, k;

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (!isdigit(ch))
        f = (ch == '-') ? -1 : 1, ch = getchar();
    while (isdigit(ch))
        x = x * 10 + (ch - '0'), ch = getchar();
    return x * f;
}

int check(double x)
{
    for (int i = 0; i < n; i++)
        f[i].val = v[i] - x * w[i], f[i].id = i + 1;
    std::sort(f, f + n);
    double sum = 0;
    for (int i = 0; i < k; i++)
    {
        sum += f[i].val;
        ans[i] = f[i].id;
    }
    return sum >= 0;
}

int main()
{
    n = read(), k = read();
    for (int i = 0; i < n; i++)
        v[i] = read(), w[i] = read();
    double l = 0, r = INF;
    while (r - l > 1e-8)
    {
        double mid = (l + r) / 2;
        if (check(mid))
            l = mid;
        else
            r = mid;
    }
    for (int i = 0; i < k; i++)
    {
        std::cout << f[i].id;
        if (i < k - 1)
            std::cout << ' ';
        else
            std::cout << '\n';
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/wyctstf/p/11372533.html