Neo's Blog

不抽象就无法深入思考
不还原就看不到本来面目!

0%

普罗米修斯字符串匹配查询语法:

=: Select labels that are exactly equal to the provided string.
!=: Select labels that are not equal to the provided string.
=~: Select labels that regex-match the provided string.
!~: Select labels that do not regex-match the provided string.

具体可以看这里:
https://prometheus.io/docs/prometheus/latest/querying/basics/

何帆宏观经济学30讲知识大纲

宏观经济最初起源于

宏观经济学-危机篇

识别危机

纸老虎

黑天鹅
灰犀牛

正视危机:不是所有的危机都只有坏处?危机红利

危机红利的两个层面:

  1. 危机是一种纠偏机制
  2. 前人的乐观加速了新技术基础设施的完善,为后人带来好处。

带有技术创新的泡沫危机,对于我们来说是危机红利。

危机会持续多久:资本负债表危机

资产的大幅缩水,使得企业资产负债表中的负债大幅增加。

增长

增长

GDP

促进经济增长的关键动力是什么:

分工?
重大创新?

索洛模型是什么?

与经济增长相关的几个要素:

人口

人口总量

人口结构

人口红利

资本

什么是资本?

技术创新

技术创新源自哪里?

政治制度

改革是万能的吗?

休克疗法?

小范围试点?

政策

财政政策

收入:税收

支出:

补贴 还是 减税?

中央政府与地方政府的关系?

积极财政:多花钱

功能财政:少花钱

货币政策

货币政策的目的

货币政策的手段

传导机制

经济周期

长期目标,短期目标

开放

汇率

汇率的定义:

汇率制度的演变历史
金本位=》

每一种制度的优缺点

金本位
优点:汇率稳定,进出口投资方便
不足:没有国内货币政策自主性

降利率之后,大家会考虑

两个国家

贸易

贸易

贸易

金融

汇率是什么?

贬值不可怕,可怕的是贬值预期!

经济增长后200年加速

人口问题的本质:虽然很难干预人口总量,但是我们干预人口在不同部门之间的分配。

人口红利,不是一个总量概念,而是一个结构概念,他说的是人口从低生产率部门向高生产率部门的转移

资本:可以用来交易的资产。

法律保护的是:交易权,交易权比所有权更重要。

资本不是看得见摸得着的实物积累,而是看不见摸不着的软性制度积累。

制度的建设:法律、银行等金融的资金价格评估等

持续增长,必须依靠技术创新。
一方面,靠经验,本质上还是靠资本的积累(生产规模越大,累积的经验就越多)

库兹涅茨曲线
短期是对的,长期是错误的。放松管制以来,贫富差距一直在变大

财富差距 vs 收入差距

资本回报率超过经济增长率

改变收入差距相对容易,但是改变财富差距很难。

没有公平,就没有效率。

如何开启工业化进程:
(1)政府规划
(2)靠市场来配置资源

经济转型:
轻工业(劳动力相对富足)
能源、交通等基础设施(因为轻工业快速发展对这些基建提出了要求:前期是可以进口的,后期进口就不划算了)
为大规模工业生产提供支持的行业(钢铁、机床、金融)

工业GDP占总GDP的40%,是谓有足够的燃料,已经进入发达国家的既定轨道。

教育、医疗、养老等问题,并不会因为经济增长而解决。

社会主要矛盾:人们日益增长的美好生活需要和不平衡、不充分的发展之间的矛盾

关于回溯,你一定要知道的

  • Q: 回溯的定义与核心思想

A: 根据百度百科的定义,回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。回溯算法(Backtrack)是一种试错思想,本质上是深度优先搜索。即:从问题的某一种状态出发,依次尝试现有状态可以做出的选择从而进入下一个状态。递归这个过程,如果在某个状态无法做更多选择,或者已经找到目标答案时,则回退一步甚至多步重新尝试,直到最终所有选择都尝试过。

  • Q:回溯算法涉及到的一些概念

A: 问题的解空间(Solution Space):针对一个问题的某一种枚举元素,我们做出多次枚举,这样子下来所有的解会构成一个树形结构,树的每一个节点是该问题的一个可能解,我们把这些可能解的集合称之为解空间。

状态(State of this problem):当前的搜索深度,以及该深度的一些局面信息

选择(avaiable Choosen based on current state) :基于当前状态能够进一步做出的选择

路径(Path of choosen for solving this problem):为了解决这个问题,走到当前状态,每一步做出的选择构成了一个列表,这个列表称之为路径

结果集(Result: all paths which can slove this problem):对于求解可行解或者所有解类型的回溯问题,我们需要把所有的可行路径记录下来,这个用来存储可行路径的容器我们称之为结果集

Q:回溯算法的三要素

A:路径:已经做出的选择

选择列表:当前状态可以做出的选择

结束条件:选择列表为空,或者找到目标

Read more »

地上有一个 m 行和 n 列的方格,横纵坐标范围分别是 0∼m−1 和 0∼n−1。

一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格。

但是不能进入行坐标和列坐标的数位之和大于 k 的格子。

请问该机器人能够达到多少个格子?

样例1
输入:k=7, m=4, n=5

输出:20
样例2
输入:k=18, m=40, n=40

输出:1484

解释:当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
但是,它不能进入方格(35,38),因为3+5+3+8 = 19。

解题思路

状态: + 访问位图

选择: 四个方向

路径:该问题不需要

结果集:计算总数

结束条件: 没有更多选择

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Solution {
public:
int t;
vector<bool> visit;
int cnt;

bool check(int i, int j) {
return (i / 10 + i % 10 + j / 10 + j % 10) <= t;
}

void dfs(int i, int j, int rows, int cols){
if (!check(i, j)) return;
visit[i * cols + j] = true;
cnt++;

int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

for (int k = 0; k < 4; ++k) {
int ni = i + dx[k], nj = j + dy[k];
if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !visit[ni * cols + nj]) {
dfs(ni, nj, rows, cols);
}
}
}

int movingCount(int threshold, int rows, int cols)
{
if (!rows && !cols) return 0;
t = threshold;
visit = vector<bool>((rows + 1) * (cols + 1), false);
dfs(0, 0, rows, cols);
return cnt;
}
};

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。

路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。

如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。

注意:

输入的路径不为空;
所有出现的字符均为大写英文字母;
样例
matrix=
[
[“A”,”B”,”C”,”E”],
[“S”,”F”,”C”,”S”],
[“A”,”D”,”E”,”E”]
]

str=”BCCE” , return “true”

str=”ASAE” , return “false”

解题思路

状态: + 访问位图

选择: 四个方向

路径:该问题不需要

结果集:不需奥

结束条件: 找到任何一个解就可以推出。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution {
public:
bool dfs(vector<vector<char>>& matrix, string &str, int u, int x, int y) {
//视频中的错误写法(测试用例不全导致)
//if (u == str.length()) return true;
//if (matrix[sx][y] != str[u]) return false;

//肯定不合适
if (matrix[x][y] != str[u]) return false;
//已经到底了,返回ok
if (u == str.length() - 1) return true;

int t = matrix[x][y];
matrix[x][y] = '#';

int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

for (int i = 0; i < 4; ++i) {
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < matrix.size() && b >= 0 && b < matrix[a].size()) {
if (dfs(matrix, str, u + 1, a, b)) return true;
}
}

matrix[x][y] = t;
return false;
}

bool hasPath(vector<vector<char>>& matrix, string &str) {
for (int i = 0; i < matrix.size(); ++i) {
for (int j = 0; j < matrix[i].size(); ++j) {
if (dfs(matrix, str, 0, i, j))
{
return true;
}
}
}

return false;
}
};

关于二叉树,你一定要知道的

  • Q:二叉树遍历

A: 作为图的一种简单形式,树也有两种遍历方式:广度优先、深度优先;广度优先的话,即对应二叉树的按层次遍历;深度优先的话,我们可以按照中间节点的访问顺序, 进一步分为先序遍历(中、左、右)、中序遍历(左、中、右)、后序遍历(左、右、中)。

  • Q:二叉树的层次遍历(BFS遍历)

A: 通常我们借助队列(queue)来辅助完成分层遍历。 还有某些情况,我们需要了解到每一个节点的深度(也就是位于第几层)。对于这种要求,我在下面的代码模版中给出了一种解决方案,供参考。

Read more »

位操作

关于位操作,你一定要知道的

位操作的常见技巧

第一个需要掌握的技巧是n & (n - 1),通过该操作我们可以让n的最后一个1变为0

第二个需要掌握的技巧是lowbit(n) = n & (-n) ,lowbit操作可以让我们获取到n的低位。

第三个需要知道的是二进制表示下不进位,例如:XOR又称作不进位加法。

第四个技巧在于 n XOR 1成对变换。

最后,掌握二进制位状态压缩的常见操作

操作 运算 说明
取出n的第k位 n & (1 << k) n & (00010000)
取出n的后k位 n & (1 << k) - 1 n & (00011111)
n的第k位取反 n xor (1 << k) n xor 00010000
n的第k位置1 n | (1 << k) n | 000010000
n的第k位置0 n & ~(1 << k) n & 1111101111

位操作相关的经典题目

题目分类 题目名称 考察点 其他说明
比特位计数
找到序列中仅出现一次的数字 位操作-XOR操作
该数二进制表示中1的个数 位操作-找1
通过位运算来实现加法 XOR技巧

01背包问题 背包问题系列
问题描述 给定N个物品,其中第i个物品的体积为$V_i$,价值为$W_i$。有一个容积为M的背包,要求选择一些物品放入背包,使得物品总体积不超过M的前提下,物品总价值和最大。https://zhuanlan.zhihu.com/p/30959069
状态表示 F[i,j]表示从前i个物品中选出了总体积为j的物品放入背包,物品的最大价值
阶段划分 主阶段:已经处理的物品数,以背包中放入到的物品总体积为附加维度
转移方程 $F[i,j]=\begin{cases}F[i-1,j] & \text { 不选第i个物品} \\ F[i-1,j-V_i] + W_i & \text{if } j \ge V_i \text{ 选第i个物品} \end{cases}$
边界 F[0,0]=0,其余为负无穷
目标 $\underset{0 \le j \le M}{\mathrm{max}}{F[N,j]}$
优化 仅依赖前一项,可以通过滚动数组或者倒序循环做空间优化

另外,还有一种状态表示:
即F[i; v] 表示前i 件物品恰放入一个容量为v 的背包可以获得的最大价值。则其状态转移方程便是:

F[i,v] = max(F[i -1, v], F[i-1 , v-C[i]] + W[i])

这样子表示状态后,目标变为F[N, M]

eg. 划分数组为两个相等的子集

找sum一半

完全背包问题 背包问题系列
问题描述 给定N个物品,其中第i个物品的体积为$V_i$,价值为$W_i$,并且有无限个。有一个容积为M的背包,要求选择一些物品放入背包,使得物品总体积不超过M的前提下,物品总价值和最大。
状态表示 F[i,j]表示从前i个物品中选出了总体积为j的物品放入背包,物品的最大价值
阶段划分 主阶段:已经处理的物品数,以背包中放入到的物品总体积为附加维度
转移方程 $F[i,j]=\begin{cases}F[i-1,j] & \text {不选第i个物品} \\ F[i,j-V_i] + W_i & \text{if } j \ge V_i & \text{ 选第i个物品} \end{cases}$
边界 F[0,0]=0,其余为负无穷
目标 $\underset{0 \le j \le M}{\mathrm{max}}{F[N,j]}$
优化 正循环做空间优化

分组背包问题 背包问题系列
问题描述 给定N个物品,其中第i组有$C_i$个物品。第i组的第j个物品的体积为$V_{ij}$,价值为$W_{ij}$。有一个容积为M的背包,要求选择一些物品放入背包,使得每组最多选择一个物品并且总体积不超过M的前提下,物品总价值和最大。
状态表示 F[i,j]表示从前i组选出了总体积为j的物品放入背包,物品的最大价值
转移方程 $F[i,j]=\begin{cases}F[i-1,j] & \text { 不选第i组的物品} \\ \underset{1 \le k \le C_i}{\mathrm{max}}{F[i - 1,j - V_{ik}] + W_{ik}} &\text{ 选第i个物品} \end{cases}$
阶段划分 主阶段:i物品组数是阶段,i与j共同组成状态,k是决策
边界 F[0,0]=0,其余为负无穷
目标 $\underset{0 \le j \le M}{\mathrm{max}}{F[N,j]}$
优化 正循环做空间优化