三分及小例题

【题目描述】选举拉票

现在你要竞选一个县的县长。你去对每一个选民进行了调查。你已经知道每一个人要选的人是谁,以及要花多少钱才能让这个人选你。要知道现在这个时代,没有百八十万元你是受买不了一个人的qwqqwq 。现在你想要花最少的钱使得你当上县长。你当选的条件是你的票数比任何一个其它候选人的多(严格的多,不能和他们中最多的相等)。请计算一下最少要花多少钱。

【数据格式】

第一行一个n ,表示投票者的人数(n<=100000);

第2~n+1 行,一个d[i] 表示每一个投票者的投票对象;紧接着一个p[i]p[i] 表示收买这个投票对象需要花多少钱
这个题主要是三分而不是二分

为什么呢?

我们可以这样想
二分是满足单调性的情况下的快速枚举

三分则是满足近似二次函数中的最值查找

二分和三分同有一个近似的特点

都是询问最大值最小或最小值最大

我们来看三分,三分的要求是最起码有两个影响结果的量,且最少一个是越来越小,最少一个是越来越大。

这就是为什么是近似的二次函数而不是光滑的二次函数

转载于:https://www.cnblogs.com/Lance1ot/p/8494578.html

<think>嗯,用户想了解回溯算法的分类和经典例题。首先,我需要确定回溯算法的主要分类方式。通常,回溯算法可以根据问题类型来分类,比如组合问题、排列问题、子集问题、分割问题、棋盘问题等等。需要确认这些分类是否准确,有没有其他可能的分类方式。 然后,经典例题部分,每个分类下需要选一两个典型题目。比如组合问题里的组合总和,排列问题里的全排列,子集问题里的子集生成,分割问题里的回文分割,棋盘问题里的八皇后等。这些例题是否足够经典,有没有更好的例子? 另外,用户可能还希望了解每个分类的基本思路和解题步骤,所以需要简要说明每个类型的特点和解决策略。比如组合问题需要考虑元素顺序无关,排列问题则顺序相关,子集问题要枚举所有可能的子集,分割问题需要找到满足条件的分割方式,棋盘问题涉及二维空间的约束。 还要注意例题的代码结构是否统一,是否需要给出伪代码或者具体代码示例。但用户可能只需要思路,所以用自然语言描述解题步骤即可。同时,要确保提到的每个例题都有回溯算法的典型应用,避免选择不适合的例子。 可能还需要考虑回溯算法的优化方法,比如剪枝,这在例题中是否有体现?例如组合总和中通过排序和提前终止来剪枝,八皇后中利用约束条件减少搜索空间。这些点是否需要提到,以展示回溯的效率优化。 最后,总结回溯算法的适用场景和解题框架,帮助用户形成整体认识。需要检查是否有遗漏的分类或例题,确保覆盖主要的应用场景。语言要简洁明了,结构清晰,方便用户理解。</think>### 回溯算法分类及经典例题 #### 一、回溯算法核心思想 回溯算法通过**暴力穷举+剪枝优化**解决问题,本质是**递归遍历决策树**,通过撤销选择(回溯)尝试所有可能路径,找到满足约束条件的解。 --- #### 二、回溯算法分类 根据问题类型可分为以下5类: 1. **组合问题** - **特点**:元素顺序无关(如$[1,2]$和$[2,1]$视为同一组合) - **经典例题**:组合总和(LeetCode 39) - **问题**:在候选集$candidates$中找出所有和为$target$的组合(元素可重复使用) - **剪枝**:排序后提前终止无效分支 ```python # 伪代码示例 def backtrack(start, path, remain): if remain == 0: result.add(path) return for i in range(start, len(candidates)): if candidates[i] > remain: break # 剪枝 backtrack(i, path + [candidates[i]], remain - candidates[i]) ``` 2. **排列问题** - **特点**:元素顺序相关(如$[1,2]$和$[2,1]$视为不同排列) - **经典例题**:全排列(LeetCode 46) - **关键**:使用`visited`数组标记已选元素 ```python def backtrack(path): if len(path) == len(nums): result.append(path.copy()) return for i in range(len(nums)): if not visited[i]: visited[i] = True backtrack(path + [nums[i]]) visited[i] = False # 撤销选择 ``` 3. **子集问题** - **特点**:枚举所有可能的子集 - **经典例题**:子集(LeetCode 78) - **技巧**:通过控制遍历起点避免重复 ```python def backtrack(start, path): result.append(path.copy()) for i in range(start, len(nums)): path.append(nums[i]) backtrack(i + 1, path) path.pop() ``` 4. **分割问题** - **特点**:将字符串/数组分割为满足条件的子段 - **经典例题**:分割回文串(LeetCode 131) - **核心**:先验证子串是否为回文 ```python def backtrack(start, path): if start >= len(s): result.append(path.copy()) return for end in range(start+1, len(s)+1): substr = s[start:end] if is_palindrome(substr): path.append(substr) backtrack(end, path) path.pop() ``` 5. **棋盘问题** - **特点**:二维空间约束下的排列组合 - **经典例题**:N皇后(LeetCode 51) - **关键**:对角线冲突检测 ```python def backtrack(row): if row == n: result.append(生成棋盘) return for col in range(n): if 列、主对角线、副对角线均无冲突: 放置皇后 backtrack(row + 1) 移除皇后 ``` --- #### 三、回溯算法解题框架 通用代码结构: ```python result = [] def backtrack(路径, 选择列表): if 满足终止条件: result.add(路径) return for 选择 in 选择列表: if 不满足剪枝条件: continue 做选择 backtrack(新路径, 新选择列表) 撤销选择 ``` --- #### 四、适用场景总结 1. 需要穷举所有可能性 2. 问题可分解为多阶段决策 3. 存在明确的约束条件用于剪枝 4. 常见于组合、排列、子集、棋盘等NP问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值