南阳理工914Yougth的最大化

来源:互联网 发布:qq空间红人软件 编辑:程序博客网 时间:2024/06/06 19:04


Yougth的最大化

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗?

输入
有多组测试数据
每组测试数据第一行有两个数n和k,接下来一行有n个数Wi和Vi。
(1<=k=n<=10000) (1<=Wi,Vi<=1000000)
输出
输出使得单位价值的最大值。(保留两位小数)
样例输入
3 22 25 32 1
样例输出
0.75


分析

利用二分法,贪心思想去解决问题


贪心就是尽量多的去装载东西,本题是使单价尽量高。


首先确定最优解l也就是f在0和最高单价t之间。


然后去判断各个单价,找出k个符合条件的相加,如果结果小于0,说明单价过高,大于0说明过低


然后去比较l和r,直至无限接近,输出最优解。


01.#include<stdio.h>
02.#include<algorithm>
03.#include<iostream>
04.#include<string.h>
05.using namespace std;
06.struct node
07.{
08.double x,y;
09.} G[10005];
10.double p[10005];
11.int n,k;
12.int Cot(double f)
13.{
14.memset(p,0,sizeof(p));
15.int i;
16.double sum=0;
17.for(i=0; i<n; i++)
18.p[i]=G[i].y-G[i].x*f;    //判断单价是否符合要求,过高还是过低
19.sort(p,p+n);
20.for(i=0; i<k; i++)
21.sum+=p[n-i-1];
22.return sum>=0;              //贪心寻找最大值
23.}
24.int main()
25.{
26.double l,r,mid,t;
27.int i;
28.while(~scanf("%d%d",&n,&k))
29.{
30.l=r=0;
31.for(i=0; i<n; i++)
32.{
33.scanf("%lf%lf",&G[i].x,&G[i].y);
34.t=G[i].y/G[i].x;
35.if(r<t)
36.r=t;
37.}
38.i=0;
39.while(i<100)                   // 等价于r-1>1e-4
40.{
41.mid=(l+r)/2;              //二分查找,寻找最优解
42.if(Cot(mid))
43.l=mid;
44.else
45.r=mid;
46.i++;
47.}
48.printf("%.2lf\n",l);
49.memset(G,0,sizeof(G));
50.}
51.return 0;
52.}

0 0