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\n",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\n",search(max)); 38 } 39 return 0; 40 }