贪心算法概念
跟DP想法差不多(其实很有差别,要好好区别,新手想法),在当前做出最好的选择。也就是说,不从整体上考虑,他所做出的近视某种意义上的局部最优解。
又是具有无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
一定要仔细分析其是否满足无后效性。
思路:
局部最优策略能导致产生全局最优解。
1.建立数学模型来描述问题。
2.把求解的问题分成若干个子问题。
3.对每一子问题求解,得到子问题的局部最优解。
4.把子问题的解局部最优解合成原来解问题的一个解。
贪心法的基本思路:
——从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:
1. 不能保证求得的最后解是最佳的;
2. 不能用来求最大或最小解问题;
3. 只能求满足某些约束条件的可行解的范围。
求解:去逼近目标,每一步都是最优解,最终得到最优解的集合,
停止:不能再继续前进。最优解得出不是最佳(这个似乎很简单啊),最大最小解问题不行(什么是最大最小解),只能求满足某些约束条件的可行解
贪心策略一旦经过证明成立后,它就是一种高效的算法。
先得知道什么时候才能用它
三:贪心算法适用的问题(前提)( 实际上,贪心算法适用的情况很少。)
贪心算法的证明围绕着:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。
四:框架
从问题的某一初始解出发;
While(朝着给定的总目标前进一步)
{
利用一些可行的决策,求出可行解的一个解元素;
}
有所有解元素组合成问题的一个可行解;
问题:如何判断是否可以用贪心;
严格的证明 可使用
有反例就是 不能用
贪心算法的一个充分必要条件:矩阵胚拟理论
贪心例子:(nice啊)
Hdoj1257:最少拦截系统
一句话:找比我小的,ok,到我这里来,我给你名利,这是你应该是比我小,你要比我最小的大,滚。
代码实现:
#include<stdio.h>
int a[1000010];
int s[1000010];
int main()
{
int i,n,j,k,flag,g;
while(~scanf("%d",&n))
{
for(i=0; i<n; i++)
scanf("%d",&a[i]);
s[0]=a[0];
k=0;
for(i=1; i<n; i++)
{
flag=0;
for(j=0; j<=k; j++)
{
if(a[i]<=s[j])
{
s[j]=a[i];
flag=1;
break;
}
}
if(flag!=1)
{
s[k+1]=a[i];
k++;
}
}
printf("%d ",k+1);
}
return 0;
}
一题A掉突然也就懂一点点贪心(真是一点点,贪心决策的证明然后在使用太难了,是的,太难了,不过随着做的题目多了应该会有感觉的,现在就是感觉暴涨啊)哈哈哈
感觉就是,贪心的决策不虚,有底气,很强悍(我是指每次对于目标的选择都有解决的方法,要么被我吃了,要么独立一派),所以就会产生目标的集合,有很多个集合,然后就可以算出集合的数目了。。。只能算出数目么?我能算集合元素么,比如背包问题,比如课程安排问题,比如装箱问题,ok接来几天,练习贪心题目,和想出这些问题的答案。