贪心算法

贪心算法

一 ·基本概念

所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。

二 ·贪心算法的基本思路

1.建立数学模型来描述问题。
2.把求解的问题分成若干个子问题。
3.对每一子问题求解,得到子问题的局部最优解。
4.把子问题的解局部最优解合成原来解问题的一个解。

三 ·贪心算法的使用条件

1、贪心选择性质
一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择。这就是贪心选择性质。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
2、最优子结构性质
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心法求解的关键所在。在实际应用中,至于什么问题具有什么样的贪心选择性质是不确定的,需要具体问题具体分析。

四 ·例题

假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false。
输入:flowerbed = [1,0,0,0,1], n = 1
输出:true
解题思路:这道题是如果有连续的三个0,那么中间的位置就可以种花,此时要将该位置的元素赋值为1。除此之外,还有两个容易忽视的地方,第一个位置和最后一个位置,如果第一个位置为0,那么该位置就可以种花。倒数第二个位置为0并且最后一个位置也为0,那么最后一个位置也可以种花。如果可以种花的位置大于等于所给的数目,返回true,否则返回false。
这是第一次做出的答案,不但没有考虑到第一个位置,而且超出了时间限制

bool canPlaceFlowers(int* flowerbed, int flowerbedSize, int n){
    int i,cnt=0;
    for(i=0;i<flowerbedSize-1;i++)
    {
        while(flowerbed[i]==0)
        {
            if(flowerbed[i-1]==0 &&flowerbed[i+1]==0)
            {
                flowerbed[i]=1;
                cnt++;
            }
        }
    }
    if(flowerbed[flowerbedSize-1]==0 && flowerbed[flowerbedSize-2]==0)
    {
        cnt++;
    }
    if(cnt<n)
    {
        return false;
    }
    else
    {
        return true;
    }
}

当n为0时,返回的总是true,这是修改后的代码:

bool canPlaceFlowers(int* flowerbed, int flowerbedSize, int n){
    int i;
    if(n==0)
    {
        return true;
    }
    for(i=0;i<flowerbedSize;i++)
    {
        if(flowerbed[i]==0 && (i==0 ||flowerbed[i-1]==0) &&(i==flowerbedSize-1 || flowerbed[i+1]==0))
        {
            n--;
            if(n<=0)
            {
                return true;
            }
            flowerbed[i]=1;
        }
    }
    return false;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值