首先,有一个简单的题目如下
海盗打劫商船
有一个商船上面装满了古董,每件古董的重量不同,但价值相同,且海盗船有最大载重限制。
问:海盗船在不翻船而且获利最大的情况下,最多能装几件古董
输入
第一行 N M
N为海盗船的最大载重,M为商船上古董的数量
第二行输入 每个古董的重量
例如:
500 10
120 204 86 58 28 264 92 345 123 58
思路:我们可以从题目中知道每一件古董的价值相同,因此要使海盗船获利最大,就要海盗船装的古董最多,所以 我们先将每一个古董重量按从小到大排序,之后就只要将古董按小到大一个个放入海盗船,即是每次都取一个剩下古董重量的最小值,古董总重量要刚好小于海盗船载重限制。是不是很简单。
代码参考:
#include <stdio.h>
int main() {
int N, M;
int num=0, all=0;
int Antique[10001];//定义一个数组储存古董重量
scanf("%d %d", &N, &M);
for (int i = 0; i < M; i++) {
scanf("%d", &Antique[i]);
}
//排序有很多种方法,有快排、桶排序等
for (int i = 0; i < M; i++) {
for (int j = i + 1; j < M; j++) {
if(Antique[i]>Antique[j]){
int tru=Antique[i];
Antique[i]=Antique[j];
Antique[j]=tru;
}
}
}
for(int i=0;i<M;i++){
all += Antique[i];
if(all>N)break;
num++;
}
printf("%d",num);
return 0;
}
贪心算法总的来说就是:根据当前情况做最优的一步,以局部最优解,逐步得到整体最优解。
如上题,要海盗获利最多,就要海盗船装的古董最多,就是贪心,能吞一点是一点。我们把上面的问题的局部最优解认为是剩下古董重量的最小值,通过排序求出。之后,就如思路说的去做了,得到整体最优解。
基本思路:
分析题目,构建数学模型;
将总问题划分为若干子问题;
寻找子问题最优解,再合并为总问题最优解。
贪心算法一般用来解决求最大或最小解,且只能确定某些问题的可行性范围。
问题应具备特征
1、贪心选择性质
一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择。这就是贪心选择性质。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解 。
2、最优子结构性质
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心法求解的关键所在。