贪心算法基本要素:
- 贪心选择性质:问题的最优解可以通过贪心选择实现(也就是先实现局部最优解,然后整体最优解可以通过一系列局部最优的选择来达到)
- 最优子结构性质:问题的最优解包含子问题的最优解
贪心算法步骤:
- 通过数学模型来描述问题
- 把求解问题分成多个子问题
- 对每一个子问题进行求解,找到局部最优解
- 把子问题的局部最优解合成原来解问题的一个解
贪心算法和动态规划区别
贪心法 | 贪心算法是自顶向下的,只查看了当前状态 | 贪心算法,仅在当前状态下做出最好选择,即局部最优选择,然后再去解做出这个选择后产生的相应的子问题。 | 最优子结构性质 贪心选择性质 |
动态规划 | 动态规划自底向上地求解了最优解包含的所有子问题 | 动态规划算法中,每步所做的选择往往依赖于相关子问题的解,因而只有在解出相关子问题时才能做出选择 | 最优子结构性质 重叠子问题性质 |
贪心法求解硬币问题:就是想办法多用面额比较大的硬币
问题描述:有1分,2分,5分,10分,50分,100分的硬币各若干枚,现在要用这些硬币来支付 W元,最少需要多少枚硬币?
代码:
#include<iostream>
using namespace std;
int V[6] = { 1,2,5,10,50,100};
int main()
{
int C[10]; //代表硬币个数
int W;
for (int i = 0;i < 6;i++) {
cin >> C[i]; //若干硬币的数量
}
cin >> W; //总金额
int count = 0;
for (int i = 5;i >= 0;i--)
{
int t = min(W/ V[i], C[i]);
W -= t * V[i];
count += t;
}
cout << "最少需要硬币数量"<<count << endl;
return 0;
}
贪心法求解乘船问题 :从给出的条件分析问题的话,则是先对这些人的体重进行排序,从低到高,然后最重的和最轻的加在一起的体重是否大于船的承载重量,进而判断做出选择。
问题描述: 有n个人,第i个人的体重为wi(0<=i<n)。每艘船的最大载重量均为C,且最多只能成两个人。试用最少的船装载所有人。
关于这道题,我用到了一个排序函数sort(),
sort()是C++给的一种排序函数,头文件为 #include <algorithm>
语法描述:sort(begin,end,cmp),cmp参数可以没有,如果没有默认非降序排序。
cmp的话,可以是function,然后在main函数外面定义它的功能,这样就可以实现按照这个函数function进行排序了。
#include<iostream>
#include <algorithm>
using namespace std;
int main()
{
int i, j ,C,count=0; //i代表轻的人,j代表重
int n, w[100];
cin >> n>>C;
for (int k = 0;k < n;k++)
{
cin >> w[k];
}
sort(w,w+n);
for (i = 0, j = n - 1;j>=i;)
{
if (w[i] + w[j] == C || w[i] + w[j] < C)
{
count++;
i++;
j--;
}
else
{
count++;
j--;
}
}
cout << "最少的船只数量为:" << count << endl;;
return 0;
}