234. 放弃测试

题目链接

234. 放弃测试

在某个课程中,你需要进行 n 次测试。

如果你在共计 bi 道题的测试 i 上的答对题目数量为 ai,你的累积平均成绩就被定义为

image

给定您的考试成绩和一个正整数 k,如果您被允许放弃任何 k 门考试成绩,您的累积平均成绩的可能最大值是多少。

假设您进行了 3 次测试,成绩分别为 5/5,0/12/6

在不放弃任何测试成绩的情况下,您的累积平均成绩是image

然而,如果你放弃第三门成绩,则您的累积平均成绩就变成了image

输入格式

输入包含多组测试用例,每个测试用例包含三行。

对于每组测试用例,第一行包含两个整数 nk

第二行包含 n 个整数,表示所有的 ai

第三行包含 n 个整数,表示所有的 bi

当输入用例 n=k=0 时,表示输入终止,且该用例无需处理。

输出格式

对于每个测试用例,输出一行结果,表示在放弃 k 门成绩的情况下,可能的累积平均成绩最大值。

结果应四舍五入到最接近的整数。

数据范围

1n1000,
0k<n,
0aibi109

输入样例:

3 1 5 0 2 5 1 6 4 2 1 2 7 9 5 6 7 9 0 0

输出样例:

83 100

解题思路

01分数规划:给定整数 a1,a2,,an 以及 b1,b2,,bn, 求一组解 xi(1in,xi=0or1), 使下式最大化:

i=1naixii=1nbixi

解法(二分):
假设 L=i=1naixii=1nbixi,存在一组解,使得 i=1n(aiLbi)xi0,即:{x1,x2,,xn}, 使得 i=1naixii=1nbixiL,即存在更大的值比当前值要大,L 过小;否则,如果任意的解都有 i=1n(aiLbi)xi<0,即:i=1naixii=1nbixi<L,即 L 比任意解都要大,L 过大,判断点在于最大值是否非负,因此具有二段性,可用二分找出最大

本题要求最多抛弃 k 门考试成绩,判断时可直接丢掉最小的 k 个值在进行判断即可

m 为不确定数,与精度有关,则:

  • 时间复杂度:O(nlogm)

代码

// Problem: 放弃测试 // Contest: AcWing // URL: https://www.acwing.com/problem/content/description/236/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const double eps=1e-6; const int N=1005; int n,k; double a[N],b[N],c[N]; bool ck(double x) { for(int i=1;i<=n;i++)c[i]=a[i]-x*b[i]; sort(c+1,c+1+n); double res=0; for(int i=k+1;i<=n;i++)res+=c[i]; return res>=0; } int main() { while(cin>>n>>k,n!=0||k!=0) { for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++)cin>>b[i]; double l=0,r=1; while(r-l>eps) { double mid=(l+r)/2; if(ck(mid))l=mid; else r=mid; } cout<<int(l*100+0.5)<<'\n'; } return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15960648.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(93)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示