前言
本文大部分是观看B站视频后记录的笔记,因此为了偷懒,本文有大量的截图,看着不舒服的话可以去看原视频。
一、贪心算法
贪心算法,顾名思义,贪心就完事了。对于这种抽象的算法,我的一贯想法是通过实例将其具体化。下面给出一个例子,好好感受:
上题的解如下:
//2021.3.8
//钞票支付问题(动态规划法也可解)
//对于此问题需要注意的是,贪心法可能得出最优也可能无法得出全局最优,这取决于硬币的种类
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> RMB = { 200,100,20,10,5,1 }; //硬币的币值
int NUM = RMB.size(); //币值种类
int x = 628; //需要支付的总价值
int count = 0; //计数,记录支付的硬币数
for (int i = 0; i < NUM; i++)
{
int use = x / RMB[i];
count += use;
x = x - RMB[i] * use;
}
cout << "总共需要" << count << "张" << endl;
return 0;
}
贪心法:每一步都做出当时看起来是最佳的选择。(注:有时候贪心算法可能无法选到全局最优的解。)
二、动态规划例题
1.分糖果
显然光看字面上对贪心法的描述你可能觉得你懂了,实际上做题后又一头雾水,下面结合一些例子我们对贪心算法做更深入的学习。
题目:
题目分析:
贪心规则:用更小的糖果满足小孩。
//2021.3.8
//糖果分配问题
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int> g = {5,10,2,9,15,9}; //孩子的需求
vector<int> s = {6,1,20,3,8}; //糖果的大小
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int child = 0; //child代表已经满足了几个孩子
int cookie = 0; //cookie代表已经尝试了几个糖果
while (cookie <= s.size() - 1 && child <= g.size() - 1)
{
if (s[cookie] >= g[child])
{
child++;
}
cookie++;
}
cout << "能够满足的小孩数量:" << child << endl;
return 0;
}
2.活动选择问题
题目大意:
贪心规则:每次找结束时间最小的活动。
//2021.3.8
//活动选择问题
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> start = { 1,3,0,5,3,5,6,8,8,2,12 };
vector<int> end = { 4,5,6,7,8,9,10,11,12,13,14 };
int now_end; //已经确定可以进行的活动的结束时间
int count = 1; //最早结束的一个活动
now_end = end[0]; //第一个活动选种,now_end=4,这是其他活动的起始时间限制,必须大于等于4
for (int i = 1; i < end.size(); i++)
{
if (start[i] >= now_end)
{
count++;
now_end = end[i];
}
}
cout << count << endl;
return 0;
}
结论
怎么找贪心规则是重点,先这样吧,以后再做到贪心算法的题会更新于此。