排序大部分是一个题的子部分,使其有序,便于其他操作。
int partition(vector<int> &nums, int l, int h) {
int i = l, j = h + 1;
while (true) {
while (nums[++i] < nums[l] && i < h) ;
while (nums[--j] > nums[l] && j > l) ;
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, l, j); //注意是j
return j;
}
随机版本
int rp(vector<int> &nums, int l, int h) {
srand(time(0));
int r = rand() % (h - l) + l;
swap(nums[v],nums[l]);
return partition(nums,l,h);
}
主要用于遍历数组,指针移动条件明确
while (l < r) {
int m = l + (r - l) / 2;
if (true)
r = m;
else
l = m + 1;
}
return l;
int lower_bound(int A[], int l, int r, int x) {
while (l < r) {
int m = l + (r - l) / 2;
if (A[m] >= x)
r = m;
else
l = m + 1;
}
return l;
}
int upper_bound(int A[], int l, int r, int x) {
while (l < r) {
int m = l + (r - l) / 2;
if (A[m] > x)
r = m;
else
l = m + 1;
}
return l;
}
以dfs + 回溯为例
for (int i = 0; i < vsize; i++) {
if (true)//满足搜索要求,如标记为1
dfs();
}
void dfs() {// 返回值视需要而定
if (true) //满足搜索值要求,如到达目的地,到达规定步数step等,做相应处理
marked[i] = true; //标记准备进入下一层dfs,有时可以在原grid标记,视具体情况
for (auto d : direction) //枚举下次dfs可能走向
dfs(); //下层
marked[i] = false; //回溯
}
queue<Typename> q;
q.push();
while (!q.emtpy()) {
int size = q.size();
while (size--) {
Typename t = q.front();
处理所得值,如标记,路径加1
判断t是否有下一层次
q.push();
q.pop();
}
}
c[i]费用, w[i]价值
for (int i = 1; i <= n; i++) {
for (int j = v; j >= c[i]; j--)
dp[j] = max(dp[j], dp[j - c[i]] + w[i])
}
for (int i = 1; i <= n; i++) {
for (int j = c[i]; j <= v; j++)
dp[j] = max(dp[j], dp[j - c[i]] + w[i]);
}
for (int i = 1; i <= n; i++) {
for (int j = v; j >= c[i]; j++) {
for (int k = 1; k <= m[i] && k * w[i] <= j; k++)
dp[j] = max(dp[j], dp[j - k * c[i]] + k * w[i]);
}
}
//二进制优化:
// 先处理物品
vector<pair<int, int>> goods;
for (int i = 1; i <= n ; i++) {
for (int k = 1; k <= m[i]; k *= 2) {
m[i] -= k;
goods.push_back(k * c[i], k * w[i]);
}
if (m[i] > 0)
goods.push_ back(m[i] * c[i], m[i] * w[i]);
}
for (auto p : goods) {
for (int j = v; j >= p.first; j++)
dp[j] = max(dp[j], dp[j - p.first] + p.second);
}
究极优化:单调队列
我不会。。。
混合背包
分情况处理即可
二维费用背包
最大重量M,m[i]
加一重循环即可
for (int i = 1; i <= n; i++) {
for (int j = v; j >= c[i]; j--) {
for (int k = M; k >= m[i]; k--)
dp[j][k] = max(dp[j][k], dp[j - c[i][k - m[i]] + w[i])
}
}
for (int i = 1; i <= n; i++) {
for (int j = v; j >= 0; j--) {
for (int k = 1; k <= s[i]; k++) {
if (j >= c[i][k])
dp[j] = max(dp[j], dp[j - c[i][k]] + w[i][k]);
}
}
}
int f[N + 1], g[N +1];
int main () {
g[0] = 1;
for (int i = 1; i < N; i++) f[i] = -INF;
for (int i = 1; i<= n; i++) {
for(int j = v; j >= c[i]; j--) {
int t = max(f[j], f[j - c[i]] + w[i]);
int s = 0;
if (t == f[j]) s += g[j];
if (t == f[j - c[i]] + w[i]) s += g[j - c[i]];
f[j] = t;
g[j] = s;
}
}
int maxw = 0;
int re = 0;
for (int i = 1; i <= N; i++) maxw = max(maxw, f[i]);
for (int i = 1; i <= N; i++) {
if (maxw == f[i]) {
re += g[i];
}
}
}
bool isPrime(int n) {
if (n <= 1) return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0)
return false;
}
return true;
}
int gcd (int a,int b) {
return b == 0 ? a : gcb(b , a % b);
}
TreeNode *preOrder(TreeNode *root) {
stack<TreeNode *>s;
s.push(root);
while (!s.empty()) {
TreeNode *temp = s.top();
s.pop();
if (temp == nullptr) continue;
//相应操作,如printf
s.push(root->right);
s.push(root->left);
}
}
TreeNode *postOrder(TreeNode *root) {
stack<TreeNode *> s;
s.push(root);
while (!s.empty()) {
TreeNode *temp = s.top();
if (temp == nullptr) continue;
//存值v
s.push(root->right);
s.push(root->left);
}
//reverse v
}
TreeNode *inOrder(TreeNode *root) {
TreeNode *cur = root;
stack<TreeNode *>s;
while (cur || !s.empty()) {
while (cur) {
s.push(cur);
cur = cur->left;
}
TreeNode *temp = s.top();
s.pop();
cur = temp->right;
}
}
染色
int color[101] = {0};
bool isBipartite(vector<vector<int>>& graph) {
for (int i = 0; i < graph.size(); i++) {
if (color[i] == 0 && !dfs(i, 1, graph)) //如果染色且相邻颜色相同即false
return false;
}
return true;
}
bool dfs(int cur, int c,vector<vector<int>>& graph) {
if (color[cur] != 0) return color[cur] == c;
color[cur] = c;
for (int n : graph[cur]) {
if (!dfs(n, -c, graph))
return false;
}
return true;
}
vector<vector<int>> edge(numCourses); //边
vector<int> in(numCourses); // 入度
for (auto p : prerequisites) {
edge[p[1]].push_back(p[0]);
}
for (int i = 0; i < numCourses; i++) {
for (auto n : edge[i])
in[n]++;
}
queue<int> q;
vector<int> re;
for (int i = 0; i < numCourses; i++) { //入度为0即可操作
if (in[i] == 0) {
re.push_back(i);
q.push(i);
}
}
while (!q.empty()) {
int temp = q.front();
q.pop();
for (int n : edge[temp]) {
in[n]--;
if (in[n] == 0) {
q.push(n);
re.push_back(n);
}
}
}
void union(int a,int b) {
int x = find(a);
int y = find(b);
if (x == y)
return ;
p[y] = x;
}
int find(int x) {
return x == p[x]? x : find(p[x]);
}