博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj2976(二分搜索,最大化平均值)
阅读量:5329 次
发布时间:2019-06-14

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

题目描述:

    给了两个数组a,b,a[i]和b[i]是相对应的,不能改变位置,去掉其中的一些元素,然后计算最大的r=∑a[i]/∑b[i];

  这道题乍一看是对a[i]/b[i]进行排序然后取前n-k个,但其实是不对的

题解:由题意得,我们要求的是r,所以对式子进行变形:设A=∑a[i],B=∑b[i],则A=r×B,A-r×B=0。所以为了求得最大的r,我们就要求使得A-rxB>0的最大的r,这样我们就可以另ci=ai-bi*r,然后对数组c进行排序即可

代码和学到的东西见下:

1 #include
2 #include
3 #include
4 #include
5 #define ll long long 6 #define mem(a,b) memset(a,b,sizeof(a)) 7 using namespace std; 8 ll a[1005],b[1005]; 9 double c[1005];10 int n,k;11 bool cmp(ll a,ll b)12 {13 return a>b;14 }15 void trans(double x)16 {17 for(int i=1;i<=n;i++)18 {19 c[i]=100*a[i]-x*b[i];此处可以不乘100,在下面输出的时候再×100,可以省去很多计算20 }21 sort(c+1,c+1+n,cmp);22 }23 void ini()24 {25 mem(a,0);26 mem(b,0);27 mem(c,0);28 }29 int main()30 {31 while(scanf("%d%d",&n,&k)&&k+n>0){32 //ini();33 for(int i=1;i<=n;i++) scanf("%d",a+i);34 for(int i=1;i<=n;i++) scanf("%d",b+i);35 double l=0,r=1000;36 for(int i=1;i<=50;i++)37 {38 double mid=(l+r)/2;39 trans(mid);40 double res=0;41 for(int j=1;j<=n-k;j++)42 {43 res+=c[j];44 }45 if(res>=0) l=mid;46 else if (res<0) r=mid;47 //printf("mid=%lf\n",mid);48 }49 printf("%d\n",(int)((l+r)/2+0.5));}//此处是四舍五入处理50 //此处也可以输出l或者r,因为二分100次后小数位数而让输出整数已经可以忽略l和r的差异51 return 0;52 }

二分的题一定要注意精度!!

转载于:https://www.cnblogs.com/codeoosacm/p/10179166.html

你可能感兴趣的文章
retrofit2 上传图片
查看>>
Linux Shell流程例子
查看>>
jQuery的三种$()
查看>>
2017.6.4 入门组 NO.4——猜数
查看>>
Eclipse 下载安装
查看>>
WebSocket 时时双向数据,前后端(聊天室)
查看>>
关于cocoa 运行时runtime
查看>>
关于python中带下划线的变量和函数 的意义
查看>>
asp.net 写入excel时,不能更新。数据库或对象为只读。
查看>>
题1简化版
查看>>
linux清空日志文件内容 (转)
查看>>
jsp中对jstl一些标签的引用方式
查看>>
100. Same Tree
查看>>
[转]java classLoader 体系结构
查看>>
mkdir命令(转)
查看>>
安卓第十三天笔记-服务(Service)
查看>>
css3学习笔记之背景
查看>>
Servlet接收JSP参数乱码问题解决办法
查看>>
【bzoj5016】[Snoi2017]一个简单的询问 莫队算法
查看>>
[dpdk] 熟悉SDK与初步使用 (二)(skeleton源码分析)
查看>>