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 2 2 2 5 3 2 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.
}