数据结构--贪心算法

原文链接(点击原文链接获取更多学习干货):

http://blog.bools.cn/archives/1277

 

  1. 贪心算法:采用贪心的策略,保证每次操作都是局部最优的,从而使最后得到的结果是全局最优的。在对问题求解时,总是做出在当前看来是最好的选择,也就是说,不从整体最优上考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者整体最优解的近似解。
  2. 解题的一般步骤是:
  • 建立数学模型来描述问题
  • 把求解的问题分成若干个子问题
  • 对每一子问题求解,得到子问题的局部最优解
  • 把子问题的局部最优解合成原来问题的一个解。

    3.该算法存在问题

  • 不能保证求得的最后解是最佳的
  • 不能用来求最大或最小解问题
  • 只能求满足某些约束条件的可行解的范围

    4.应用

  • 分配问题

有一群孩子和一堆饼干,每个孩子有一个饥饿度,每个饼干都有一个大小。每个孩子只能吃最多一个饼干,且只有饼干的大小大于孩子的饥饿度时,这个孩子才能吃饱。求解最多有多少孩子可以吃饱。
输入输出样例

输入:1 2

           1 2 3

输出:2

题解:

因为饥饿度最小的孩子最容易吃饱,所以我们先考虑这个孩子。为了尽量使得剩下的饼干可以满足饥饿度更大的孩子,所以我们应该把大于等于这个孩子饥饿度的、且大小最小的饼干给这个孩子。满足了这个孩子之后,我们采取同样的策略,考虑剩下孩子里饥饿度最小的孩子,直到没有满足条件的饼干存在。

public class FindContentChildren {
    static int solution(int[]children,int[ ]cookies) {
        Arrays.sort(children);
        Arrays.sort( cookies);
    int child =0 ;//能吃饱的孩子数量
    int cookie = 0 ;
    while (child < children.length && cookie < cookies.length){
        if ( children[child] <=cookies[cookie++]) 
                child++;
    }
        return child ;
    }
}
  • 买卖股票的最佳时机

给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

class Solution {
public:
    int maxProfit(vector<int>& prices) {   
        int ans = 0;
        int n = prices.size();
        for (int i = 1; i < n; ++i) {
            ans += max(0, prices[i] - prices[i - 1]);
        }
        return ans;
    }
};
  • 设置路灯

题目描述

小Q正在给一条长度为n的道路设计路灯安置方案。

为了让问题更简单,小Q把道路视为n个方格,需要照亮的地方用'.'表示, 不需要照亮的障碍物格子用'X'表示。

小Q现在要在道路上设置一些路灯, 对于安置在pos位置的路灯, 这盏路灯可以照亮pos - 1, pos, pos + 1这三个位置。

小Q希望能安置尽量少的路灯照亮所有'.'区域, 希望你能帮他计算一下最少需要多少盏路灯。

输入描述:

输入的第一行包含一个正整数t(1 <= t <= 1000), 表示测试用例数
接下来每两行一个测试数据, 第一行一个正整数n(1 <= n <= 1000),表示道路的长度。
第二行一个字符串s表示道路的构造,只包含'.'和'X'。

输出描述:

对于每个测试用例, 输出一个正整数表示最少需要多少盏路灯。

示例1

输入

2
3
.X.
11
...XX....XX

输出

1
3

思路:这是一个贪心算法。每遇到一个`.`,就是放置一个路灯,然后从这开始的三个位置都不用考虑。如果遇到了`'X'`,就是直接跳过。

// 贪心 每次遇到.;在.的后边一个位置放置路灯,这样就会用最少的路灯了

#include <string>
#include  <iostream>

int main(void) {  
  int n;
  std::cin>>n;       // 测试案例个数
  
  while(n--) {  
    int count =0;   // 每个测试案例
    int length; 
    std::string lamps;
    
    std::cin>>length;  // 路灯长度
    std::cin>>lamps;   // 路灯
    
    for(int pos =0; pos < length; ) {  
      if(lamps[pos] =='.') { 
        pos +=3;
        ++count;
      }
      else {  
        pos +=1;
      } 
    } //for
    
    // 每次通过一个测试案例,就是输出一次
    std::cout<<count<<std::endl;
  }  //while
 
  return 0; 
}

欢迎关注技术公众号,获取更多C++学习干货!

 

我们能为你提供什么?

技术辅导:C++、Java、嵌入式软件/硬件

项目辅导:软件/硬件项目、大厂实训项目

就业辅导:就业全流程辅导、技术创业支持

对接企业HR:培养输送优质性人才

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值