POJ-2976 Dropping tests(01分数规划入门)

POJ2976 Dropping tests——P4377 [USACO18OPEN] Talent Show G 【分数规划二分法+贪心/背包】 阅读详情

01分数规划问题:

所谓的01分数规划问题就是指这样的一类问题,给定两个数组,a[i]表示选取i的收益,b[i]表示选取i的代价。如果选取i,定义x[i]=1否则x[i]=0。每一个物品只有选或者不选两种方案,求一个选择方案使得R=sigma(a[i]*x[i])/sigma(b[i]*x[i])取得最值,即所有选择物品的总收益/总代价的值最大或是最小。


分析(详):

大体概括一下,就是定义一个函数F(L) = sigma(a[i]*x[i])-L*sigma(b[i]*x[i]),其实就是将R换为自变量L后上述式子的变形,分离参数,得到F(L)=sigma((a[i]-L*b[i])*x[i])。如果我们固定L在某个方案下能导致F(L)大于0,这代表存在更优的L,所以我们不断变换L,寻找一个临界L使得不存在一种方案,能够使F(L)>0。另d[i]=(a[i]-L*b[i]),显然d数组是随着L的增大而单调减的,所以根据d数组去判断边界,如果d数组的相应方案的和>=0则表明可能存在更优解,否则不存在。

所以根据性质,很自然想到用二分去求解。二分的下界一般都是取为0(a[i],b[i]一般都是大于0的),但是上界怎么求呢?假设两个方案a1,b1和a2,b2。它们分别的比率是a1/b1,a2/b2,组合的比率是(a1+a2)/(b1+b2)

a1/b1 - (a1+a2)/(b1+b2)化简后是(a1b2-a2b1)/(b1(b1+b2))

a2/b2 - (a1+a2)/(b1+b2)化简后是(a2b1-a1b2)/(b2(b1+b2))

由于正负取决于分子,所以可以看出两者组合的比率必定小于其中一个单独的比率。所以上界就是寻找一个最大的单独比率。

二分是一个非常通用的办法,但是二分的时候我们只是用到了F(L)>0这个条件,而对于使得F(L)>0的这组解所求到的R值没有使用。因为F(L)>0,我们已经知道了R是一个更优的解,与其漫无目的的二分,为什么不将解移动到R上去呢?求01分数规划的另一个方法就是Dinkelbach算法,它就是基于这样的一个思想,他并不会去二分答案,而是先随便给定一个答案,然后根据更优的解不断移动答案,逼近最优解。由于对每次判定使用的更加充分,所以它比二分会快上很多。但是,它的弊端就是需要保存这个解,而我们知道,有时候验证一个解和求得一个解的复杂度是不同的。二分和Dinkelbach算法写法都非常简单,各有长处,要根据题目谨慎使用。


POJ-2976题意:

给定A数组B数组,从中选择N-K个使得R最大,输出Round(100*R);

代码1(二分方法 79ms):

#include <algorithm>
#include <cstdio>
#define LL long long
using namespace std;
const int maxn = 1005;
const double eps = 1e-6;
LL a[maxn], b[maxn];
double d[maxn];
int n, k;
LL _round(double x)
{
	if(x-(LL)x < 0.5) return (LL)x;
	else return (LL)x+1;
}
bool jg(double v)
{
	double tmp = 0;
	for(int i = 1; i <= n; ++i)
	d[i] = a[i]-b[i]*v;
	sort(d+1, d+n+1);
	for(int i = 0; i < k; ++i)
	tmp += d[n-i];
	return tmp >= 0;
}
void work()
{
	double l = 0, r = 0, mid;
	for(int i = 1; i <= n; ++i)
	if(1.0*a[i]/b[i] > r) r = 1.0*a[i]/b[i];
	while(r-l >= eps)
	{
		mid = (l+r)/2.0;
		if(jg(mid)) l = mid;
		else r = mid;
	}
	printf("%lld\n", _round(l*100));
}
int main()
{
	while(scanf("%d %d", &n, &k), (n||k))
	{
		for(int i = 1; i <= n; ++i)
		scanf("%lld", &a[i]);
		for(int i = 1; i <= n; ++i)
		scanf("%lld", &b[i]);
		k = n-k; work();
	}
	return 0;
}


代码2(Dinkelbach算法 32ms)

#include <algorithm>
#include <cstdio>
#include <cmath>
#define LL long long
using namespace std;
const int maxn = 1005;
const double eps = 1e-6;
struct node
{
	int a, b;
	double d;
} p[maxn];
int cmp(node x, node y) {return x.d < y.d;}
int n, k;
LL _round(double x)
{
	if(x-(LL)x < 0.5) return (LL)x;
	else return (LL)x+1;
}
void work()
{
	double ans = 1.0, tmp, x, y;
	do
	{
		tmp = ans;
		for(int i = 1; i <= n; ++i)
		p[i].d = p[i].a-p[i].b*tmp;
		sort(p+1, p+n+1, cmp);
		x = y = 0.0;
		for(int i = 0; i < k; ++i)
		x += p[n-i].a, y += p[n-i].b;
		ans = x/y;
	}
	while(fabs(tmp-ans) >= eps);
	printf("%lld\n", _round(ans*100));
}
int main()
{
	while(scanf("%d %d", &n, &k), (n||k))
	{
		for(int i = 1; i <= n; ++i)
		scanf("%d", &p[i].a);
		for(int i = 1; i <= n; ++i)
		scanf("%d", &p[i].b);
		k = n-k; work();
	}
	return 0;
}


继续加油~

2023年5月青少年软件编程Python等级考试四级真题(含答案和解析) 电子学会,2023年5月,青少年软件编程,Python等级考试,四级真题(含答案和解析) 阅读详情

相关推荐

转录组数据提取技巧汇总

数据整理是数据分析的前提,而数据的正确提取则是数据整理的前提。

zfyyzhys的博客 1784

POJ---2976(二分,最大化平均值详细讲解)

题意: 最大化平均值的模型: 有N个物品的重量和价值分别为Wi和Vi,从中选取K个物品使得单位重量的价值最大。也就是使得K个物品的ΣVi /ΣWi最大。 使用二分搜索解决这类问题: ΣVi /ΣWi >= x也就是Σ(Vi-x*Wi)>=0。X越大,式子左边越小,一直逼到=0的边界! 贪心思想去找最大的可行解x即可:对Vi-X*Wi排序,选取前K个看是否>=0!  本题也就是这个模

sgh666666的博客 814

ROS教程(四):RVIZ使用教程(详细图文)

前言 根据前面的教程已经学会了创建功能包,那么本篇文章主要内容则是通过节点来发布数据至RVIZ

Leslie的博客 17万+

POJ 2976 (最大化平均值)

题意: 给出n个题的分数,给定n个二元组(a,b),删除k个二元组, 使得剩下的a元素之和与b元素之和的比率最大(比率最后乘100输出) though: a/b = max(m),可以化简为a-m*b ,当a/b最大的时候a-m*b <= 0,所以 二分m。找到精度足够小的解。 #include <iostream> #include <cstdio> #include <cst

Since_natural_ran 667

【深度学习总结_02】在自己的数据集微调SAM

使用医疗影像数据微调SAM

qq_41234663的博客 1万+

Scale-up,scale-out技术概述

本文系统分析了Scale-up与Scale-out两种扩展技术在现代计算中的应用与发展。Scale-up通过增强单节点性能,适用于高耦合任务,而Scale-out通过横向扩展节点,实现高可用性和无限扩展。在芯片层面,Chiplet技术推动Scale-up发展;在数据中心层面,二者协同工作构建强大集群。光模块在长距离高带宽传输中发挥关键作用。文章对比了NVIDIA、AMD和Broadcom三家公司的技术路线,指出NVIDIA采用封闭生态,AMD选择开放标准,Broadcom则主导底层连接技术。未来发展方向将聚

元直的博客 1446

poj解题报告——2976

设最后的结果k,那么(a1+a2+a3+.....)/(b1+b2+b3+....)=k,转换一下(a1-k*b1)+(a2-k*b2)+......=0,那么可以知道任取k个差值要尽量大,那么也就是说若后面结果是大于0的,那么肯定可以找到更大的值满足要求。 #include #include #include #include using namespace std; const int

Lingfu74的专栏 627

大模型风电功率预测:短期,超短期,中长期的完整实现与代码详解

本文全面介绍了基于深度学习大模型的风电功率预测方法,涵盖超短期(15分钟-1小时)、短期(1-6小时)和中长期(1天-1周)三种时间尺度。文章详细阐述了数据准备与特征工程,包括数据收集、预处理和可视化分析。针对不同时间尺度,分别介绍了Temporal Fusion Transformer (TFT)、Informer和N-BEATS模型的构建、训练与评估方法,并提供了完整的开源代码实现。此外,文章还探讨了模型部署与生产环境集成,包括模型保存与加载、实时预测API以及模型监控与再训练。最后,文章总结了关键创新

专注AI大模型,软件混淆,授权 1892

POJ 2976(01分数规划)

题目链接:http://poj.org/problem?id=2976   题目大意:求去掉k组数据后,a的和/b的和*100的最大值   题目思路:假设最大值为x,则需要的就是取n-k个数字a[i]的和/b[i]的和=x,那么我们可以移项,把b[i]的和乘过去然后移到左边减掉。问题也就转变成了 选n-k个数字使得a[i]-b[i]*x的和等于0,那么就可以采用二分来枚举x,对a[i]-b...

smilestruggler_Fly To Higher 333

Android功耗系列专题理论之十一:高通QCOM平台待机功耗问题分析方法

本文详细介绍了高通QCOM平台待机功耗问题的分析方法。首先强调测试环境标准化的重要性,包括关闭无线功能、日志记录和非必要传感器。重点分析了硬件连接检查、驱动配置验证、电源管理策略优化等关键步骤。文章详细讲解了射频校准、时钟源/中断分析、子系统状态检查等专业技术方法,并提供了具体的命令行操作示例。此外还介绍了外设拆解、外灌电压测试等硬件排查手段,以及功耗分解板、波形分析等高级诊断技术。最后强调了固件版本验证和环境因素测试的必要性,为工程师提供了系统性的功耗问题排查思路。

772

2.3 MMU Notifier(上):KVM 催生的页表变化通知

探讨了MMU Notifier机制的作用及其在虚拟化等场景中的应用。当CPU页表发生变更(如munmap、页面迁移等操作)时,需要通知拥有"第二套页表"的子系统(如KVM的EPT/NPT、IOMMU、GPU等)失效其映射。MMU Notifier通过订阅-通知机制实现这一功能,核心数据结构包括mmu_notifier订阅对象和回调接口mmu_notifier_ops。当CPU页表修改时,通过mmu_notifier_range描述变更范围,调用订阅者的回调函数进行同步,确保外部MMU与CPU页表一致性。

图形/计算GPU的驱动与虚拟化技术分享园地 1037

[模板]Poj2976 Dropping tests(01分数规划入门)

传送门 最大化∑ai∑bi=r\frac{\sum a_i}{\sum b_i}=r∑bi​∑ai​​=r 那么∑ai−r∗∑bi=0\sum a_i-r*\sum b_i=0∑ai​−r∗∑bi​=0 那么对于所有不同的选取物品方式,∑ai\sum a_i∑ai​和∑bi\sum b_i∑bi​是各不相同的 令f(r)=B−Arf(r)=B-Arf(r)=B−Ar 画在坐标轴就是很多条直线,斜率负数,且交yyy轴正半轴 我们要求的就是最靠右的和xxx轴的交点,此时是最大值 怎么求? 考虑在x=midx=m

jziwjxjd的博客 498

2026 年 3 月青少年软编等考 C/C++ 三级测试题解析

摘要 本文包含三部分内容: 单选题(10题):考察C++基础语法和数据结构知识,涉及vector、栈、队列的操作和特性。 判断题(10题):测试对动态数组、栈、队列、字符串操作的理解,包括内存管理、访问方式和函数返回值等。 编程题(1题):模拟火车站售票窗口排队场景,要求根据输入输出各窗口的排队情况,重点考查队列的实际应用和边界条件处理。 答案解析详细,涵盖常见编程考点,适合检验基础知识的掌握程度。

发布少儿编程考级的真题和优秀竞赛题解析,以及一些讲义。 251

POJ 2976-Dropping tests(01分数规划入门)

https://blog.youkuaiyun.com/Hhaile/article/details/8883652 这篇写得挺不错 这个就是入门的01分数规划,二分答案x,将ai-x*bi从大到小排序,去前n-k个,判断是否满足sigm(ai)-sigm(bi*x)>=0,满足 说明还有最优解即更新l=mid,否则更新r=mid; #include <stdio.h> #inc...

weixin_30278311的博客 116

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【POJ2976】Dropping tests (01分数规划入门题)

(小声bb:话说好像下周就可以停课了(flag)!终于可以去见学长们啦~ 虽然月考挂了) 在这里学习的分数规划——>传送门 简单总结一下 设函数f(r)=sigma(a[i]*x[i])-r*sigma(b[i]*x[i]) 变形 f(r)=sigma((a[i]-r*b[i])*x[i]) 假如r已知若预处理出d[i]=a[i]-r*b[i] 那式子就变得很简洁了 f...

Android66666的博客 222

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

POJ 2976 Dropping tests 01分数规划 入门

题意: 有n个物品,每个物品有ai,bi两个属性。让你从n个里面,剔除k个,使得剩下的n-k个物品的 100*sum(a[i])/sum(b[i])最大。 思路: 比较基础的01分数规划。 假设answer为最终结果,answer >= 100*sum(a[i]*x[i])/sum(b[i]*x[i]),则有100*sum(a[i]*x[i]) - answer*sum(b[i]*x[i

743

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Poj 2976 Dropping tests (01分数规划入门)

题目链接:http://poj.org/problem?id=2976 Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17461   Accepted: 6060 Description In a certain course, you take n te...

passer__的博客 213

POJ 2976 Dropping tests(01分数规划入门)

Dropping tests Time Limit:1000MS Memory Limit:65536K Total Submissions:11367 Accepted:3962 Description In a certain course, you takentests. If you getaiout of...

weixin_30474613的博客 140

Poj-2976 Dropping tests (01分数规划)

POJ 2976 Dropping tests 题解 《挑战程序设计竞赛》 [Algorithm]01分数规划——Update:2012年7月27日 // 条件C(x):=可以选择使得单位重量的价值不小于x #include<iostream> #include<cstdio> #include<cstring> #include<algorithm&...

ó 219

POJ 2976 Dropping tests —————— 01分数规划,二分

POJ 2976 Dropping tests 给出n个a和b,让选出n-k个使得 100∗∑i=1nai∑i=1nbi100*\frac{\sum_{i=1}^{n} a_i}{\sum_{i=1}^{n}b_i}100∗∑i=1n​bi​∑i=1n​ai​​ 最大 01规划问题,看这里 看完就会了 这里用的是二分的方法 /*--------- Hongjie ----------*/ /** ...

鸿杰 的博客 303

Dropping tests POJ - 2976(01分数规划问题)

01分数规划问题:Dropping tests POJ - 2976 黑洞内窥: 给出公式:, 多组输入,每组输入n,k,n个ai,n个bi,,你可以删除最多k组ai,bi,来使得上式的值达到最大。 思维光年: 最简单粗暴的想法:取出每对ai,bi的分数比例,sort一下,从后往前取,输出完事。。 wa了两次后,,,感觉有坑,,应该是精度问题不够,,, 于是暴力二分概率(...

浦柳人的博客 204

POJ - 2976 Dropping tests(二分 + 01分数规划)

Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9635   Accepted: 3368 Description In a certain course, you take n tests. If you get ai out of

qq_18661257的专栏 1158

[poj 2976]Dropping tests 01分数规划

Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5992   Accepted: 2076 Description In a certain course, you take n tests. If you get ai out of 

一维空间 756

POJ 2976 Dropping tests:01分数规划【二分】

题目链接:http://poj.org/problem?id=2976 题意:   共有n场考试,每场考试你得的分数为a[i],总分为b[i]。   你可以任意去掉k场考试。   问你最大的 100.0 * ( ∑ a[i] / ∑ b[i] )的值。(四舍五入) 题解:   相当于从n场考试中选n-k场。   二分:     二分最大答案 ∑ a[i]...

a1392136的博客 100

[POJ2976] Dropping tests

题意n个二元组(ai,bi)(a_i,b_i),选定n-K个二元组使得∑ai∑bi\frac{\sum a_i}{\sum b_i}最大题解基本的01分数规划问题 weighti=valuei−r⋅costiweight_i = value_i-r\cdot cost_i,max{f(r)}max\{f(r)\}求和前n+K大的weightiweight_i即可。 至于为什么WA嘛,改改精度,c

ztx 2058
上一篇: 51nod-1524 可除图的最大团(DP)
下一篇: HDU-5773 The All-purpose Zero(LIS变形)
薄层
博客等级 码龄10年 242粉丝 289原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值