赞
踩
上一节中我提到的搜索是遍历状态空间中的所有解。而贪心(Greedy Algorithm
)是沿着一条看上去最优的路径走到底,永不反悔
首先证明边界情况是正确,然后归纳证明一般的情况。假定给一个序列 a 1 , a 2 , a 3 , . . . , a n a_1,a_2,a_3,...,a_n a1,a2,a3,...,an求出一个区间 [ l , r ] [l, r] [l,r],使得 a l + . . . + a r a_l + ... + a_r al+...+ar最大。这里我们考虑使用归纳法证明最大子段和的贪心算法
void greedy_algorithm(std::vector<int> &nums) {
int maxSum = 0;
int subSum = 0;
int i = 0;
while (i < nums.size()) {
subSum += nums[i];
if (subSum > 0) {
maxSum = subSum > maxSum ? subSum : maxSum;
} else {
subSum = 0;
}
++i;
}
std::cout << "maxSum = " << maxSum << std::endl;
}
先依靠贪心算法得出最优解,再证明:将任意步骤的决策替换为任意的其他选择,最后结果都不可能达到更优。假定有 n n n个物品各自的重量,背包负重上限为 N N N,要求在不超过负重上限的情况下,尽可能的多带物品
如果了解动态规划的朋友,可能会觉得这两个算法很像。这里我们先简单的做一些对比,等后续讲解动态规划的时候,再来重提两个算法的区别
贪心 | 动态规划 |
---|---|
最优子结构 | 最优子结构、无后效性、子问题重叠 |
为后继的每一个阶段决策保留了足够多的子问题 | 为后继的每一个阶段决策保留了足够多的子问题 |
最优解包含子问题的最优解,但不是任意子问题的最优解都一定对应原问题的最优解 | 当前最优解一定是子问题的最优解 |
给出一个分子分母分别为 m o l mol mol和 d e n den den构成的分数,要求将其分解为一系列互不相同的单位分数(分子为 1 1 1),并且要求分解的单位分数越少越好,如果单位分子数量一样,那么最小的单位分数越大越好
int comm_factor(int m, int n) { if (n > m) std::swap(m, n); int z = n; while (m % n != 0) { z = m % n; m = n; n = z; } return z; } void egyptian_fractions(int mol, int den) { int n = 0, r = 0; std::cout << mol << "/" << den << " = "; do { n = den / mol + 1; std::cout << "1/" << n << " + "; mol = mol * n - den; den = den * n; r = comm_factor(den, mol); den /= r; mol /= r; } while (mol > 1); std::cout << "1/" << den << std::endl; }
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree) — 百度百科
假定有 n n n个权值,则构造出的哈夫曼树有 n n n个叶子结点。 n n n个权值分别设为 w 1 w_1 w1、 w 2 w_2 w2、…、 w n w_n wn,则哈夫曼树的构造规则为:
代码相对简单,这里就不再详细展开了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。