山脉二分找中值|子集型回溯

++回溯枚举情况 出口处check++

lc1601

不选 选

++DFS枚举所有请求的选与不选,统计++满足所有节点进出人数平衡的请求组合,返回最大请求数量

class Solution {

public:

int maximumRequests(int n, vector<vector<int>>& requests) {

int ans = 0;

int l = requests.size();

vector<int> path(n,0);

//i表示当前遍历的元素,cnt是当前满足的请求

function<void(int,int)> dfs = \&(int i,int cnt)

{

if(i==l)

{

for(int k = 0;k < n;++k)

++if(pathk != 0) return; //check
ans = max(ans,cnt);
++

return;

}

//不选

dfs(i+1,cnt);

//选

pathrequests\[i0]--;//出去

pathrequests\[i1]++;//进去

dfs(i+1,cnt+1);

//恢复现场

pathrequests\[i0]++;//出去

pathrequests\[i1]--;//进去

};

dfs(0,0);

return ans;

}

};

lc2044

之前是用for迭代写的

刷题单发现还可以回溯写(`・ω・´)

先计算数组所有元素的总按位或值

再通过DFS枚举子集,统计按位或等于该最大值的子集数量

trick:

if (subset_or == total_or)

ans += 1 << (n - i);

当子集按位或等于最大值时,剩++余 n-i 个元素选或不选都不影响结果++,直接用 2^(n-i) 快速统计这类子集的数量。

class Solution {

/*

输入:nums = 3,2,1,5

输出:6

解释:子集按位或可能的最大值是 7 。有 6 个子集按位或可以得到 7 :

  • 3,5

  • 3,1,5

  • 3,2,5

  • 3,2,1,5

  • 2,5

  • 2,1,5

*/

public:

int countMaxOrSubsets(vector<int>& nums) {

int ++total_or = reduce(nums.begin(), nums.end(), 0, bit_or());++

int n = nums.size();

int ans = 0;

auto dfs = \&(this auto&& dfs, int i, int subset_or) {

++if (subset_or == total_or) {
ans += 1 << (n - i);
++

return; //cut

}

if (i == n)

return;

dfs(i + 1, subset_or); // 不选 numsi

dfs(i + 1, ++subset_or | numsi); // 选++

};

dfs(0, 0);

return ans;

}

};

lc1255

预处理: 统计字母库存后

DFS枚举单词选或不选的所有组合

验证字母是否充足并计算得分,最终返回最大得分

class Solution {

public:

int maxScoreWords(vector<string> &words, vector<char> &letters, vector<int> &score) {

int ans = 0, left26{};

for (char c : letters)

++leftc - 'a';

function<void(int, int)> dfs = \&(int i, int total)

{

if (i < 0) { // 到头了

++ans = max(ans, total);++

return;

}

// 不选 wordsi

dfs(i - 1, total);

// 选 wordsi

bool ok = true;

for (char c : wordsi) {

++if (leftc - 'a'-- == 0)++

++ok = false; // 剩余字母不足++

++total += scorec - 'a'; // 累加得分++

}

if (ok)

++dfs(i - 1, total);++

// 恢复现场

++for (char c : wordsi)++

++++leftc - 'a';++

};

dfs(words.size() - 1, 0);

return ans;

}

};

lc1095

山脉数组 两次二分

先二分查找山脉数组的峰值位置

再在峰值左侧升序区间和右侧降序区间分别二分查找目标值

优先返回左侧找到的索引

/**

* // This is the MountainArray's API interface.

* // You should not implement it, or speculate about its implementation

* class MountainArray {

* public:

* int get(int index);

* int length();

* };

*/

class Solution

{

public:

int binary_search(MountainArray & mountainArr, int target, int L, int R, int sign)

{

target = sign * target;

while (L <= R)

{

int mid = (L + R) >> 1;

int cur = sign * mountainArr.get(mid);

if (cur == target)

return mid;

else if (cur < target)

L = mid + 1;

else

R = mid - 1;

}

return -1;

}

int findInMountainArray(int target, MountainArray &mountainArr)

{

int L = 0, R = mountainArr.length() - 1;

while (L <= R)

{

int mid = (L + R) >> 1;

if (mountainArr.get(mid) < mountainArr.get(mid + 1))

L = mid + 1;

else

R = mid-1;

}

int peak_idx = L;

int idx = binary_search(mountainArr, target, 0, peak_idx, 1 );

if (idx != -1)

return idx;

return binary_search(mountainArr, target, peak_idx + 1, mountainArr.length() - 1, -1 );

}

};

相关推荐
地平线开发者19 小时前
【征程6】校准量化中HistogramObserver解析
算法
OuO-219 小时前
笔试强训 Day 34:ISBN 号码、kotori 和迷宫、矩阵最长递增路径
java·算法·矩阵
程序喵大人20 小时前
【C++进阶】STL算法与函数对象 - 04 find、count和any_of把查询写成意图
开发语言·c++·算法
豆沙沙包?20 小时前
c++中引用(P7-P11)
java·c++·算法
不会代码的小猴21 小时前
标准模板库(STL)
开发语言·c++·笔记·算法
ZhouDevin21 小时前
算法论文/高效微调4——DoRA:权重分解的低秩适配方法
算法
AI探索先锋21 小时前
A* 路径规划:四种算法的进化史-学习
学习·算法
旖旎夜光21 小时前
LeetCode 202:快乐数(双指针问题) —— 题解
数据结构·c++·算法·leetcode·双指针
cpp_25011 天前
P1113 [USACO02FEB] 杂务
数据结构·c++·算法·动态规划·图论·拓扑排序·洛谷题解
月光船幽幽1 天前
门控函数SHS阈值与调制机制解析
人工智能·python·算法