博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最大化平均值问题
阅读量:6404 次
发布时间:2019-06-23

本文共 1542 字,大约阅读时间需要 5 分钟。

最大化平均值问题

题意

n个物品,有体积和价值里拿k个,问怎么样拿,k个物品的平均价值(总价值/总体积)最大。

笺释

如果按照价值/体积排序,贪心选取之后并不能保证最后的总平均价值最大。

转化为不等式就是

a+w1/b+v1>a+w2/b+v2

w1/v1>w2/v2 并不能保证上述不等式成立。

这让我想起了,那个题之所以能拿就拿是因为最终要最优化的是全部价值之和,就等于是用密度不同的物质去填满一定体积的球,那肯定是能用密度大的就用密度大的了。
而这道题的话,我们二分价值,只需要确定n个物品里选k个能否达到这个平均价值即可,如果能,平均价值变大,否则变小。
而在确定了价值x的基础上可以对n个物品进行排序。

因为最终要确定的是sum(v)/sum(w)>=x,也就是sumv>=sum(w)*x,对于求和来说,可以将x放入求和号内,最终确定只要v-w*x大的就一定选。按照v-w*x排序后。选前k个就好了。

完整代码

#include
#define MAXN 1005#define INF 0x3f3f3f3ftypedef long long ll;using namespace std;int n,k;double x;struct node{ double w,v;}nodes[MAXN];bool cmp(node n1,node n2){ return n1.v-n1.w*x>n2.v-n2.w*x;}int check(){ sort(nodes+1,nodes+1+n,cmp); double ans1=0,ans2=0; for(int i=1;i<=k;i++) { ans1+=nodes[i].v; ans2+=nodes[i].w; // printf("B %f %f\n",nodes[i].v,nodes[i].w); } // printf("%f %f\n",ans1,ans2); if(ans1/ans2>=x) { return 1; } else { return 0; }}int main(){ scanf("%d %d",&n,&k); double l=INF; double r=0; for(int i=1;i<=n;i++) { scanf("%lf %lf",&nodes[i].w,&nodes[i].v); // printf("C %f %f\n",nodes[i].v,nodes[i].w); l=min(l,nodes[i].v/nodes[i].w); r=max(r,nodes[i].v/nodes[i].w); } int flag=0; while(l<=r) { flag++; if(flag>100) { break; } x=(l+r)/2; if(check()) { l=x; } else { r=x; } } printf("%f\n",l);}

转载于:https://www.cnblogs.com/SoniciSika/p/9030815.html

你可能感兴趣的文章
安装pywin32
查看>>
如何进行文章分类和标签的数据库设计
查看>>
黑科技:程序猿如何打造属于自己的分体键盘
查看>>
“Zabbix poller processes more than 75% busy”警报问题解决
查看>>
PhpStorm创建Drupal模块项目开发教程
查看>>
swap分区的作用,如何决定swap分区的大小
查看>>
自己总结的oracle开发中需要注意的几点
查看>>
性能调优之tomcat生产部署关键参数设置
查看>>
老李分享: Oracle Performance Tuning Overview 翻译
查看>>
微信小程序学习之externalClasses的用法
查看>>
Linux的基础目录命名法则及功用
查看>>
计模式:单例模式
查看>>
iptables详解
查看>>
Python之Linux下开发环境部署
查看>>
在地址栏加上网站的标志、LOGO图片
查看>>
Linux文件系统小结
查看>>
linux下安装DB2的详细步骤
查看>>
fastdfs企业级分布式存储
查看>>
mysql
查看>>
十五周四次课
查看>>