Yougth的最大化(好题,二分查找 0 1分数规划)

 

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
 1 #include<stdio.h>
 2 #include<algorithm>
 3 #define MAX(x,y) x>y?x:y
 4 using namespace std;
 5 const int MAXN=10010;
 6 struct Node{int v,w;
 7 };
 8 Node res[MAXN];
 9 double cont[MAXN];
10 int n,k;
11 int fun(double mid){//大神们都说这是0-1分数规划。。。 
12     for(int i=0;i<n;i++){
13         cont[i]=res[i].v-mid*res[i].w;
14     }
15     sort(cont,cont+n);double sum=0;
16     for(int i=n-1;i>=n-k;i--)sum+=cont[i];//从大到小代表k个物品使得单位重量的价值最大 
17     //printf("%lf
",mid);
18     return sum>=0?1:0;
19 }
20 double abs(double x){
21     return x>0?x:-x;
22 }
23 double search(double max){//二分查找 
24     double left=0,right=max,mid;
25     while(right-left>1e-10){mid=(left+right)/2;
26         if(fun(mid))left=mid;
27         else right=mid;
28     }
29     return mid;
30 }
31 int main(){
32     while(~scanf("%d%d",&n,&k)){double max=0;
33         for(int i=0;i<n;i++){
34         scanf("%d%d",&res[i].w,&res[i].v);
35         max=MAX(max,res[i].v*1.0/res[i].w);//醉了,少了个MAX错了无数次;;;; 
36         }
37         printf("%.2f
",search(max));
38     }
39     return 0;
40 }
原文地址:https://www.cnblogs.com/handsomecui/p/4690691.html