POJ 3111-K Best (01分数规划)

这篇和上篇POJ2976类似,只是多了一个保存答案,用数组保存即可。

要注意初始化,即我们二分的时候可能永远都更新不了l,即一直执行r=mid,直到退出循环,所以此时我们ans数组就不会更新,因此我们在开始的时候就要初始ans数组,以防这种情况。

例如数据 5 3 0 1 0 1 0 1 0 1 0 1,即v都是0,w都比0大,此时我们二分就将一直执行r=mid.

#include <stdio.h>
#include <string.h>
#include<iostream>
#include <vector>
#include <algorithm>
#include<functional>
using namespace std;
typedef long long ll;
#define eps 1e-6
const int N = 1e6 + 10;
int  n,k;
int a[N],b[N];
struct node{
    double val;
    int pos;
    bool operator<(const node &other)const{
        return val>other.val; 
    }
}c[N];
vector<int> ans;
bool check(double  t)
{
    double sum=0;
    for (int i = 1; i <= n; i++)
        c[i].val = a[i] - t*b[i],c[i].pos=i;
    sort(c + 1, c + n + 1);
    for (int i = 1; i <= k; i++)
        sum += c[i].val;
    return sum >= 0;
}
int main()
{
    cin >> n >> k;
    for (int i = 1; i <= k; i++)
        ans.push_back(i);
        for (int i = 1; i <= n; i++)
            scanf("%d%d", &a[i],&b[i]);
        double l = 0, r = 1e7;
        while (r - l > eps)
        {
            double mid = (l + r) / 2;
            if (check(mid)) {
                ans.clear();
                l = mid;
                for (int i = 1; i <= k; i++)
                    ans.push_back(c[i].pos);
            }
            else r = mid;
        }
        if (ans.size() > 0)
        {
            for (int i = 0; i < ans.size() - 1; i++)
                printf("%d ", ans[i]);
            printf("%d", ans[ans.size() - 1]);
        }
        
    return 0;
}

 

posted @ 2019-03-26 21:51  TLE自动机  阅读(113)  评论(0编辑  收藏  举报