mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
add algorithm
This commit is contained in:
parent
0433ed7027
commit
c5e9dc6c5d
56
algorithm/MST.md
Normal file
56
algorithm/MST.md
Normal file
@ -0,0 +1,56 @@
|
||||
# 最小生成树
|
||||
|
||||
## 1. Prim算法
|
||||
### 1.1 算法描述
|
||||
TODO
|
||||
|
||||
### 1.2 代码
|
||||
|
||||
``` C++
|
||||
int Prim(vector<vector<int> >&G, int start){
|
||||
/*
|
||||
用Prim算法求最小生成树的代价.
|
||||
Prim算法:
|
||||
又称"加点法", 每次选择横跨最小生成树内外的边中代价最小的边对应的点, 加入到最小生成树中。
|
||||
参数:
|
||||
G: 连通图的邻接矩阵
|
||||
start: 起始结点编号
|
||||
|
||||
时间复杂度O(v^2)
|
||||
*/
|
||||
int n = G.size(); // 顶点数
|
||||
int res = 0;
|
||||
|
||||
vector<int>processd(n, 0); // 是否已经被处理(即是否已在生成树中)
|
||||
processd[start] = 1;
|
||||
|
||||
vector<int>lowCost(n, 0); // 记录每个结点到生成树结点集合的最短边长度
|
||||
for(int i = 0; i < n; i++)
|
||||
if(i != start) lowCost[i] = G[start][i];
|
||||
|
||||
// 不断加入剩下的 n-1 个结点到生成树结点集合中
|
||||
for(int i = 1; i < n; i++){ // 循环 n-1 次
|
||||
int mincost = 0x7FFFFFFF, v = -1;
|
||||
for(int j = 0; j < n; j++){
|
||||
if(!processd[j] && mincost >= lowCost[j]){
|
||||
mincost = lowCost[j];
|
||||
v = j;
|
||||
}
|
||||
}
|
||||
if(v == -1){
|
||||
cout << "Error: 输入的图不是连通图!!!" << endl;
|
||||
return -1;
|
||||
}
|
||||
// 将结点v加入到已处理集合中
|
||||
processd[v] = 1; res += mincost;
|
||||
// 更新每个结点到生成树结点集合的最短边长度
|
||||
for(int j = 0; j < n; j++)
|
||||
if(!processd[j] && G[v][j] < lowCost[j])
|
||||
lowCost[j] = G[v][j];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Kruskal算法
|
||||
TODO
|
9
algorithm/README.md
Normal file
9
algorithm/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# 经典算法总结
|
||||
|
||||
## 图
|
||||
|
||||
* [最小生成树](MST.md)
|
||||
|
||||
## 动态规划
|
||||
|
||||
* [背包问题](pack_problem.md)
|
56
algorithm/pack_problem.md
Normal file
56
algorithm/pack_problem.md
Normal file
@ -0,0 +1,56 @@
|
||||
# 背包问题
|
||||
|
||||
## 1 算法描述
|
||||
|
||||
背包问题系列总结见[我的博客](https://tangshusen.me/2019/11/24/knapsack-problem/)。
|
||||
|
||||
## 2 代码
|
||||
|
||||
``` C++
|
||||
/*
|
||||
https://tangshusen.me/2019/11/24/knapsack-problem/
|
||||
01背包, 完全背包, 多重背包模板(二进制优化).
|
||||
2020.01.04 by tangshusen.
|
||||
|
||||
用法:
|
||||
对每个物品调用对应的函数即可, 例如多重背包:
|
||||
for(int i = 0; i < N; i++)
|
||||
multiple_pack_step(dp, w[i], v[i], num[i], W);
|
||||
|
||||
参数:
|
||||
dp : 空间优化后的一维dp数组, 即dp[i]表示最大承重为i的书包的结果
|
||||
w : 这个物品的重量
|
||||
v : 这个物品的价值
|
||||
n : 这个物品的个数
|
||||
max_w: 书包的最大承重
|
||||
*/
|
||||
void zero_one_pack_step(vector<int>&dp, int w, int v, int max_w){
|
||||
for(int j = max_w; j >= w; j--) // 反向枚举!!!
|
||||
dp[j] = max(dp[j], dp[j - w] + v);
|
||||
}
|
||||
|
||||
void complete_pack_step(vector<int>&dp, int w, int v, int max_w){
|
||||
for(int j = w; j <= max_w; j++) // 正向枚举!!!
|
||||
dp[j] = max(dp[j], dp[j - w] + v);
|
||||
|
||||
// 法二: 转换成01背包, 二进制优化
|
||||
// int n = max_w / w, k = 1;
|
||||
// while(n > 0){
|
||||
// zero_one_pack_step(dp, w*k, v*k, max_w);
|
||||
// n -= k;
|
||||
// k = k*2 > n ? n : k*2;
|
||||
// }
|
||||
}
|
||||
|
||||
void multiple_pack_step(vector<int>&dp, int w, int v, int n, int max_w){
|
||||
if(n >= max_w / w) complete_pack_step(dp, w, v, max_w);
|
||||
else{ // 转换成01背包, 二进制优化
|
||||
int k = 1;
|
||||
while(n > 0){
|
||||
zero_one_pack_step(dp, w*k, v*k, max_w);
|
||||
n -= k;
|
||||
k = k*2 > n ? n : k*2;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue
Block a user