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 namespace std;
 6 const double eps=1e-8;
 7 const int MAXN=100005;
 8 int N,K;
 9 int sgn(double x)
10 {
11     if(fabs(x)<eps) return 0;
12     if(x>0) return 1;
13     else return -1;
14 }
15 struct Node
16 {
17     int n;
18     double v,w;
19     Node(){}
20     Node(int nn,double vv,double ww)
21     {
22
23         n=nn;
24         v=vv;
25         w=ww;
26     }
27 }L[MAXN];
28 struct OUT
29 {
30     int n;
31     double sum;
32     OUT(){}
33     OUT(int nn,double ss)
34     {
35         n=nn;
36         sum=ss;
37     }
38 };
39 bool cmp(OUT x,OUT y)
40 {
41     return sgn(y.sum-x.sum)<0;
42 }
43 void Init()
44 {
45     double a,b;
46     for(int i=0;i<N;i++)
47     {
48         scanf("%lf%lf",&a,&b);
49         L[i]=Node(i+1,a,b);
50     }
51 }
52 void Solve()
53 {
54     OUT O[MAXN];
55     double l=0.0;
56     double r=1e7;
57     while(sgn(r-l)!=0)
58     {
59         double mid=l+(r-l)/2.0;
60         for(int i=0;i<N;i++)
61             O[i]=OUT(L[i].n,L[i].v-L[i].w*mid);
62         sort(O,O+N,cmp);
63         double temp=0;
64         for(int i=0;i<K;i++)
65             temp+=O[i].sum;
66         if(sgn(temp)<0) r=mid;
67         else l=mid;
68     }
69     for(int i=0;i<K-1;i++)
70         printf("%d ",O[i].n);
71     printf("%d\n",O[K-1].n);
72 }
73 int main()
74 {
75     while(scanf("%d%d",&N,&K)!=EOF)
76     {
77         Init();
78         Solve();
79     }
80     return 0;
81 }
时间: 2024-08-05 11:18:44

POJ 3111 K Best 二分 最大化平均值的相关文章

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 ,二分,牛顿迭代

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 &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 2976 3111(二分-最大化平均值)

POJ 2976 题意 给n组数据ai,bi,定义累计平均值为: 现给出一个整数k,要求从这n个数中去掉k个数后,最大累计平均值能有多大?(四舍五入到整数) 思路 取n?k个数,使得累计平均值最大. 定义C(x)表示能否取得n?k个数,使得累计平均值≥x.然后二分搜索最大的x. 可以这样判断可行性: 只需要从大到小选取n?k个(100?ai?x?bi)并求和sum,根据sum≥0来判断(上述的S表示n?k个元素下标的集合) #include <iostream> #include <al

POJ 3111 K Best(最大化平均值)

题目链接:click here~~ [题目大意]有n个物品的重量和价值分别是Wi和Vi,从中选出K个物品使得单位重量的价值最大,输出物品的编号 [解题思路]:最大化平均值的经典.参见click here~~ 代码: //#include <bits/stdc++.h> #include <stdio.h> #include <math.h> #include <string.h> #include <iostream> #include <

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 (二分搜索之最大化平均值之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(二分答案)

[题目链接] 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 贪心 二分

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