标签:决定 技术 one 描述 ack return pen 珠宝 struct
描述
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 }
标签:决定 技术 one 描述 ack return pen 珠宝 struct
原文地址:http://www.cnblogs.com/ibilllee/p/7651952.html