POJ 3111 K Best

二分,排序,贪心。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar(); x = 0;while(!isdigit(c)) c = getchar();
    while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar();  }
}

const int maxn=100010;
struct X { int v,w;}s[maxn];
int n,k,ans[maxn];
struct XX {double num; int id;}t[maxn];
double Max;

bool cmp(XX a,XX b){ return a.num>b.num; }

bool check(double x)
{
    for(int i=1;i<=n;i++)
    {
        t[i].num=1.0*s[i].v-x*s[i].w;
        t[i].id=i;
    }
    sort(t+1,t+1+n,cmp);

    double sum=0;
    for(int i=1;i<=k;i++) sum=sum+t[i].num;

    if(sum+eps>=0)
    {
        for(int i=1;i<=k;i++) ans[i]=t[i].id;
        return 1;
    }
    return 0;
}

int main()
{
    while(~scanf("%d%d",&n,&k))
    {
        for(int i=1;i<=n;i++)
            scanf("%d%d",&s[i].v,&s[i].w);

        double L=0.0,R=10000000.0;
        int t=50;
        while(t--)
        {
            double mid=(L+R)/2;
            if(check(mid)) L=mid;
            else R=mid;
        }

        for(int i=1;i<=k;i++)
        {
            printf("%d",ans[i]);
            if(i<k) printf(" "); else printf("\n");
        }
    }
    return 0;
}
时间: 2024-10-13 08:57:12

POJ 3111 K Best的相关文章

poj 3111 K Best ,二分,牛顿迭代

poj 3111  K Best 有n个物品的重量和价值分别是wi和vi.从中选出k个物品使得单位重量的价值最大. 题解: 1.二分做法 2.牛顿迭代 效率比较: 二分做法: 转换成判断是否存在选取K个物品的集合S满足下面的条件: sigma(vi) / sigma(wi) >= x   {vi∈S, wi∈S} -->   simga(vi - x*wi) >= 0 这样我们对  yi= vi - x*wi {1<=i<=n}从大到小排序,计算sum(yi) {1<=

poj 3111 K Best 最大化平均值 二分思想

poj 3111 K Best 最大化平均值 二分思想 题目链接: http://poj.org/problem?id=3111 思路: 挑战程序竞赛书上讲的很好,下面的解释也基本来源于此书 设定条件C(x):=可以选择使得单位重量的价值不小于x 如何判定C(x)是否可行 假设选了某个物品的集合是S,那么单位重量的价值是:\[ \sum\limits_{i \in S} {v_i } /\sum\limits_{i \in S} {w_i } \] 因此就变成了判断是否存在S满足下面的条件:\[

poj 3111 K Best 参数搜索之牛顿迭代法

题意: 给n个元素,每个元素有两个属性(v,w),现在要从中选k个,使sum(v)/sum(k)最大. 分析: 参数搜索的入门题,牛顿迭代比二分快很多. 代码: //poj 3111 //sep9 #include <iostream> #include <algorithm> #include <cmath> using namespace std; const int maxN=100024; int n,k; double s0,s1; struct Node {

POJ 3111 K Best 贪心 二分

题目链接: http://poj.org/problem?id=3111 题目描述: 解题思路: 代码: 这是我错的代码......一会儿回来改啊......一会儿回来可能会很沮丧 #include <iostream> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iterator> #include <cm

POJ 3111 K Best(二分答案)

[题目链接] http://poj.org/problem?id=3111 [题目大意] 选取k个物品,最大化sum(ai)/sum(bi) [题解] 如果答案是x,那么有sigma(a)>=sigma(b*x) 至于选取,就可以根据a-b*x排序,贪心选取即可. 对于输出物品的id,因为在不断逼近结果的过程中,排序的结果也不断在调整 所以我们最后的得到的排序结果的前k个就是答案. [代码] #include <cstdio> #include <algorithm> usi

POJ 3111 K Best &amp;&amp;NYOJ 914 (二分+ 贪心,最大化平均值)

链接:NYOJ:click here, POJ:click here 题意:(最大化平均值,挑战编程P143) 有n个物品的重量和价值分别是w[i]和v[i],从中选出K个物品使得单位重量的价值最大.(1<=k<=n<=10^41<=w[i],v[i]<=10^6) 一般想到的是按单位价值对物品排序,然后贪心选取,但是这个方法是错误的,比如对nyoj的例题来说,从大到小地进行选取,输入的结果是5/7=0.714对于有样例不满足.我们一般用二分搜索来做(其实这就是一个01分数规

POJ 3111 K Best 二分 最大化平均值

1.题意:给一共N个物品,每个物品有重量W,价值V,要你选出K个出来,使得他们的平均单位重量的价值最高 2.分析:题意为最大化平均值问题,由于每个物品的重量不同所以无法直接按单位价值贪心,但是目标值有界且能判断与最后答案的大小关系,所以用二分来做 3.代码: 1 # include <iostream> 2 # include <cstdio> 3 # include <cmath> 4 # include <algorithm> 5 using names

poj 3111 K Best (二分搜索之最大化平均值之01分数规划)

Description Demy has n jewels. Each of her jewels has some value vi and weight wi. Since her husband John got broke after recent financial crises, Demy has decided to sell some jewels. She has decided that she would keep k best jewels for herself. Sh

POJ - 3111 K Best 平均值最大(01分数规划)

题目大意:有n颗珍珠,每颗珍珠有相应的价值和代价,要从中挑出K颗珍珠,使得(这k颗珍珠的总价值/这k颗珍珠的代价 )达到最大 解题思路:平均值最大,要注意精度 给出01分数规划的详细解读 < http://www.cnblogs.com/perseawe/archive/2012/05/03/01fsgh.html> #include<cstdio> #include<algorithm> #include<cstring> using namespace