首页 > 其他分享 >「分数规划」学习笔记及做题记录

「分数规划」学习笔记及做题记录

时间:2024-10-05 12:22:25浏览次数:8  
标签:分数 sz int sum 笔记 times 做题 权值 最大值

「分数规划」学习笔记及做题记录

做题时发现不会分数规划,赶紧来学一下。

分数规划用于求解下面一类问题:

有 \(n\) 个物品,第 \(i\) 个物品的价值为 \(a_i\),费用为 \(b_i\)。从中选择若干个物品,使得价值与费用的比值 \(\dfrac{\sum a}{\sum b}\) 最大/最小。

另一种更严谨的表示方法是:给第 \(i\) 个物品钦定 \(w_i \in \{1, 0\}\) 表示选/不选该物品,使得 \(\dfrac{\sum_{i=1}^{n} w_i \times a_i}{\sum_{i=1}^{n} w_i \times b_i}\) 最大。

分数规划使用二分法来求解该问题。以求最大值为例,二分比值 \(x\),求解判断问题:是否存在方案,使比值大于等于 \(x\) (由于是实数二分,加不加等于其实无所谓)。那么式子化为:

\[\dfrac{\sum_{i=1}^{n} w_i \times a_i}{\sum_{i=1}^{n} w_i \times b_i} \ge x \\ \Longrightarrow \sum_{i=1}^{n} w_i \times (a_i - x \times b_i) \ge 0 \]

这样,只需求出不等号左边式子的最大值。如果该最大值不小于 \(0\),说明比值可以达到 \(x\),否则不可以。

可以发现,这样转化问题的最大好处是:我们消去了除法。如果把 \(a_i - x \times b_i\) 看作第 \(i\) 个物品的新权值 \(c_i\),那么我们只要研究如何取到这一个权值的和的最大值,而不用研究两个权值的比,这往往能带来极大的便利。

而分数规划的主要难点也就在于求出新权值 \(c_i\) 的最大和。下面以几道例题为例来讲解。(由于二分的过程是类似的,下面只研究如何求出新权值的最大和)

例题

I. [USACO18OPEN] Talent Show G

问题转化后:第 \(i\) 个物品的权值为 \(a_i\),费用为 \(w_i\),并且总费用不小于 \(W\)

可以用背包 dp 来求解。设 \(f(i, v)\) 表示在前 \(i\) 个物品中,选择若干个使得费用和为 \(v\) 时,权值的最大值。但这里有一个问题:\(w_i \le 10^6\),因此 dp 数组的第二维要开到 \(n \times w \le 2.5 \times 10^5\),这样的时空复杂度都是无法接受的。但我们注意到,大于等于 \(W\) 的重量都可以直接视为 \(W\),这样并不改变答案。也就是说,\(f(i, W)\) 表示的实际上是费用和不小于 \(W\) 时,权值的最大值。转移的时候,使用“我为人人”的转移方法,可以使代码实现更简洁。详见代码。

bool check(double x)
{
	vector<double> a(n + 1);
	for(int i = 1; i <= n; i++)
		a[i] = t[i] - x * w[i];
	vector<vector<double>> f(n + 1, vector<double>(W + 1, -1e9));
	f[0][0] = 0;
	for(int i = 1; i <= n; i++)
	{
		copy(f[i - 1].begin(), f[i - 1].end(), f[i].begin()); // 如果不用滚动数组,必须写这一行
		for(int v = 0; v <= W; v++) // “我为人人” 
		{
			int j = min(W, v + w[i]);
			f[i][j] = max(f[i][j], f[i - 1][v] + a[i]);
		}
	}
	return f[n][W] >= 0;
}

提交记录

II. [JSOI2016] 最佳团体

树上背包即可。

void dfs(int u)
{
	sz[u] = 1, f[u][1] = a[u];
	for(int v: G[u])
	{
		dfs(v);
		sz[u] += sz[v];
		for(int i = min(m, sz[u]); i > 1; i--)
		{
			for(int j = max(0, i + sz[v] - sz[u]); j <= min(i - 1, sz[v]); j++)
				f[u][i] = max(f[u][i], f[v][j] + f[u][i - j]);
		}
	}
}

bool check(double x)
{
	for(int i = 1; i <= n; i++)
		a[i] = val[i] - x * w[i];
	
	fill(f.begin(), f.end(), vector<double>(m + 1, -1e9));
	dfs(rt);
	return f[rt][m] >= 0; 
}

标签:分数,sz,int,sum,笔记,times,做题,权值,最大值
From: https://www.cnblogs.com/dengstar/p/18447754

相关文章

  • 《代码大全》阅读笔记1(2024.10.4)
    第一章:引言软件构建的艺术:介绍了软件开发的复杂性,以及编写高质量代码的重要性。强调了良好的编码习惯不仅能提高代码的可读性和可维护性,也能降低后期的开发成本。第二章:软件构建的哲学质量的重要性:讨论了软件质量的定义,强调高质量软件不仅包括功能的正确性,还包括可维护性、......
  • 2024.10.5 笔记
    贪心的证明方法(5个):咕咕咕贪心、DP。贪心优化DP。有简单策略:贪心。无:DP。手玩样例。手玩。兜底。重复:copy。一行多个最小值。不管。得到答案后转成0/1。反悔贪心的一般策略:先把所有都选上,再反悔。IOI那道题和这道题。感觉反悔贪心常用堆。手写堆,支持插入、......
  • CSP-JS多省分数线分析!复赛如何准备?(附复赛流程视频)
    截止目前已经有多个省份CSP-JS的分数线已经出了,很多省份比去年提升了不少,像河南等地都提升了20多分,不过也有一些省份,天津比去年提升分数却不是很多。还有很多省份分数线没出,各位家长想要预估是否能够晋级的,以下是已出分数线省份表格统计:目前已出分数线省份省份入门组......
  • 【做题纪要】10月“我想要太多太多装满房子,欢乐自由每刻每时” -- 《我想要太多太多
    P6717[CCO2018]BoringLectures问题相当于求两个距离不大于\(k\)的数对的和的最大值我们把修改改为先删除再进行插入的操作,对于插入操作我们使用线段树在左端点维护每个区间的答案维护区间最大的最大值+次大值,区间最值即可更新答案。咋删?不好删,那么就不删,直接离线然后线......
  • 红日靶机(三)笔记
    VulnStack-红日靶机三概述相交于前边两个靶场环境,靶场三的难度还是稍难一点,有很多兔子洞,这就考验我们对已有信息的取舍和试错,以及对渗透测试优先级的判断。涉及到对数据库操作的试错,对joomla框架cve的快速学习,php中用到disabled_function的bypass,对linux内核提权的取舍......
  • 数据容器之集合(笔记)
    集合的特点不支持重复元素(去重)而且顺序不能保证(乱序,无下标索引)允许被修改小总结列表[]元祖()字符串""集合{}语法#语法{"sasa","kaka","papa","enen"}#字面量set_1={"sasa","kaka","papa","enen"}#用......
  • 【刷题笔记】2024.10.4 test
    2024.10.4test虹色的北斗七星思路题目要求\[maxn-minn-len\]的最大值,其中\(maxn\)为区间的最大值,\(minn\)为区间的最小值,\(len\)为区间的长度注意性质,最优的状态一定是区间的左右端点为最大值和最小值时。因为,如果区间左右端点不为最大值或最小值,那么区间长度就可以继续......
  • 学习笔记 - log
    目录1.定义2.性质3.计算公式本人实力不济,如有错误或建议及补充,请指出(评论或私信都行)1.定义如果\(x^n=a\),那么\(n\)叫作以\(x\)为底\(a\)的对数。记作\(n=\log_xa(x>0\text{且}x\neq1)\)。2.性质\(\log_aa^x=x\)(定义)\(\log_a1=0(a^0=1)\)\(\log_aa=1(a^1=a)\)负数......
  • 斜率优化学习笔记
    斜率优化模板题,有三倍经验,难度逐渐递增,建议从前做到后。P2365任务安排,P10979任务安排2,P5785[SDOI2012]任务安排。(但是我这种做法P10979和P5785没有区别。思路:设\(f_i\)表示第\(i\)个任务加工后所需的最小总费用,那么就有转移式。\[f_i=\displaystyle\min_{j=0}^{......
  • 国庆 CF 做题记录
    CF2002F2考虑F1,当\(n=m\)时,我们默认\(l\gef\)。此时我们可以发现一个比较正确的策略:先从\((0,0)\)跳到满足\(p\)是质数的\((p,0)\)处,然后再跳到满足\(q\)是小于\(p\)的质数的\((p,q)\)处,然后再暴力BFS。不会证明,可以达标找出这样的结论。当\(n>m\)时,注......