zoukankan      html  css  js  c++  java
  • K Besk [POJ 3111]

    描述
      Demy有n颗宝石。她的每个珠宝都有一些价值vi和重量wi。自从丈夫约翰在最近的金融危机爆发后,已经决定出售一些珠宝。她决定自己会保留最好的珠宝。她决定保留这样的宝石,使他们的具体价值尽可能大。也就是说,表示某组宝石S = {i1,i2,...,ik}的具体值。
      Demy想选择这样的k宝石,他们的具体值是最大可能的。帮助她这样做。

    输入
      输入文件的第一行包含n - Demy得到的珠宝数量,k - 她想保留的珠宝数量(1≤k≤n≤100 000)。
      以下n行包含两个整数,每个-vi和wi(0≤vi≤10e6,1≤wi≤10e6,所有vi的和和全部wi之和不超过10e7)。

    输出
      输出k个数字 - 戴姆必须保留的珠宝数量。如果有几个解决方案,输出任何一个。

    样例输入
    3 2
    1 1
    1 2
    1 3

    样例输出

    1 2

    题目大意:
    n个珠宝,每个珠宝对应一个重量wi和价值vi,现在要从中找出k个,使的这k个珠宝的单位重量的价值最大,输出这k个珠宝的编号。

    解题思路:
    首先,我们给出一个贪心思路:计算出每个珠宝的单位价值,从大到小选择k个,这个贪心思路是显然错误的。感性证明:单位价值只体现了比值,在数值大小不一样的时候,比值不可做加法。
    所以,我们来换一个角度:
    我们设一个集合S的单位价值≥x
    则有
    ∑vi / ∑wi ≥ x (i∈S)
    变形得
    ∑(vi - x × wi )≥0(i∈S)
    所以,对vi-x×wi排序,选择前k个,检验是否≥0
    而x我们可以通过二分来枚举

    Code

     1 #include<set>
     2 #include<map>
     3 #include<cmath>
     4 #include<queue>
     5 #include<stack>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<iostream>
     9 #include<algorithm>
    10 #define RG register int
    11 #define ll long long
    12 #define inf (1<<30)
    13 #define eps (1e-15)
    14 #define maxn 100005
    15 #define rep(i,a,b) for(RG i=a;i<=b;i++)
    16 #define per(i,a,b) for(RG i=a;i>=b;i--)
    17 using namespace std;
    18 int n,k;
    19 struct Dat{
    20     double v,w;
    21 }dat[maxn];
    22 double tmp[maxn];
    23 inline int read()
    24 {
    25     int x=0,f=1;char c=getchar();
    26     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    27     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    28     return x*f;
    29 }
    30 
    31 inline bool cmp(const double &a,const double &b)
    32 {
    33     return a>b;
    34 }
    35 
    36 inline bool judge(double x)
    37 {
    38     rep(i,1,n)    tmp[i]=dat[i].v-x*dat[i].w;
    39     sort(tmp+1,tmp+1+n,cmp);
    40     double sum=0;
    41     rep(i,1,k)    sum+=tmp[i];
    42     return sum>=0;
    43 }
    44 
    45 struct Ans{
    46     int id;
    47     double val;
    48 }ans[maxn];
    49 
    50 inline bool cmp2(const Ans &a,const Ans &b)
    51 {
    52     return a.val>b.val;
    53 }
    54 
    55 inline void work(double x)
    56 {
    57     rep(i,1,n)    ans[i].id=i,ans[i].val=dat[i].v-x*dat[i].w;
    58     sort(ans+1,ans+1+n,cmp2);
    59     rep(i,1,k) printf("%d ",ans[i].id);
    60 }
    61 
    62 void solve()
    63 {
    64     double l=0,r=inf;
    65     rep(i,1,50)
    66     {
    67         double mid=(l+r)/2;
    68         if(judge(mid))    l=mid;
    69         else r=mid;
    70     }
    71     work(r);
    72 }
    73 
    74 int main()
    75 {
    76     n=read(),k=read();
    77     rep(i,1,n)    dat[i].v=read(),dat[i].w=read();
    78     solve();
    79     return 0;
    80 }
    点击展开代码
  • 相关阅读:
    python 约束与异常处理
    ActiveMQ
    SpringMVC项目,启动项目怎么总是报找不到log4j.properties文件
    java 字符串处理
    java面向对象学习笔记
    JSONArray遍历
    get/post方式调用http接口
    IO流认识
    Apache Mina 入门实例
    “wsimport -keep ”生成客户端报错“Use of SOAP Encoding is not supported.”
  • 原文地址:https://www.cnblogs.com/ibilllee/p/7651952.html
Copyright © 2011-2022 走看看