Yougth的最大化

来源:互联网 发布:云计算和大数据面试 编辑:程序博客网 时间:2024/05/17 09:22

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
 帮助资料。
我的代码:
#include <iostream>#include <cstdio>#include <algorithm>using namespace std;int w[10010],v[10010];double cnt[10010];int n,k;int fun(double mid)//0-1分数规划{int i;double sum;for (i=0;i<n;++i){cnt[i]=v[i]-mid*w[i];//cnt数组是随着mid的增大而单调减的}sort(cnt,cnt+n);for (sum=0,i=n-1;i>=n-k;--i)//之所以要找最大的k个数是因为sum有可能<0,不符合二分找sum趋近于0的思想{sum+=cnt[i];}return sum>=0?1:0;}double BS(double R)//二分搜索最大的单位价值{double L=0,mid;while (R-L>0.00001)//二分法很久没用,竟然忘了R-L>0.00001为条件,用了L<=R结果死循环了//L<=R是在数组中用的{mid = ( L + R)/2;if (fun(mid)){L=mid;}else{R=mid;}}return mid;}int main(){int i;double max;while (~scanf("%d %d",&n,&k)){max=0;for (i=0;i<n;++i){scanf("%d %d",&w[i],&v[i]);max = max > v[i]*1.0/w[i] ? max : v[i]*1.0/w[i] ;//找出最大的单位价值,做二分上界}printf("%.2lf\n",BS(max));}return 0;}

标程:
 #include <cstdio>#include <algorithm>#include <cmath>const double exps = 1e-3;struct node{    int v,w;    double c;};node p[10010];int n,k;bool cmp(const node &x,const node &y){    return x.c > y.c;}double test(){    double ans,tmp = 0;    int x,y;    while(true){        ans = tmp;        for(int i = 0; i < n; i++)            p[i].c = p[i].v - ans*p[i].w;        std::sort(p,p+n,cmp);        x = y = 0;        for(int i = 0; i < k; i++){            x += p[i].v;            y += p[i].w;        }        tmp = x*1.0/y;        if(fabs(tmp - ans) < exps) return ans;    }}int main(){    while(~scanf("%d %d",&n,&k)){        for(int i = 0; i < n; i++)            scanf("%d %d",&p[i].w,&p[i].v);        printf("%.2f\n",test());    }    return 0;}        


0 0