acm学习总结(3)

此次总结是关于贪心算法的。
贪心算法的理解:所谓贪心算法就是最优解,类似于小学学的时间规划问题如何在一个限制因素下获得最大利益。从贪心算法的定义可以看出,贪心算法不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。
贪心算法的缺点:这种策略是一种很简洁的方法,对许多问题它能产生整体最优解,但不能保证总是有效,因为它不是对所有问题都能得到整体最优解。
使用贪心算法求解问题应该考虑如下几个方面:
(1)候选集合A:为了构造问题的解决方案,有一个候选集合A作为问题的可能解,即问题的最终解均取自于候选集合A。
(2)解集合S:随着贪心选择的进行,解集合S不断扩展,直到构成满足问题的完整解。
(3)解决函数solution:检查解集合S是否构成问题的完整解。
(4)选择函数select:即贪心策略,这是贪心法的关键,它指出哪个候选对象最有希望构成问题的解,选择函数通常和目标函数有关。
(5)可行函数feasible:检查解集合中加入一个候选对象是否可行,即解集合扩展后是否满足约束条件。
(以上摘自ppt)
以下是贪心算法的某些例题

  1. 背包问题
    但是背包问题还分两种情况一种就是物品可分割一种就是物体不可分割,这两种情况都是考虑物品的性价比;
    可分割情况:struct bag{
    int w; //物品的重量
    int v; //物品的价值
    double c; //性价比
    }a[1001]; //存放物品的数组
    然后性价比降序排列(运用sort)
    //形参n是物品的数量,c是背包的容量M,数组a是按物品的性价比降序排序
    double knapsack(int n, bag a[], double c)
    {
      double cleft = c;        //背包的剩余容量
      int i = 0;
      double b = 0;          //获得的价值
      //当背包还能完全装入物品i
      while(i<n && a[i].w<cleft)
      {
        cleft -= a[i].w;
        b += a[i].v;
        i++;
      }
      //装满背包的剩余空间
      if (i<n) b += 1.0a[i].vcleft/a[i].w;
      return b;
    }这也是基本的结构。
  2. 这是删数问题
    string a;        //n位数a
    int k;
    cin>>a>>k;
    //如果k≥n,数字被删完了
    If (k >= a.size()) a.erase();
    else while(k > 0)
    {
      //寻找最近下降点
      int i;
      for (i=0; (i<a.size()-1) && (a[i] <= a[i+1]); ++i);
      a.erase(i, 1);    //删除xi
      k- -;
    }
    //删除前导数字0
    while(a.size() > 1 && a[0] == ‘0’)
      a.erase(0, 1);
    cout<<a<<endl;
    3.提水的问题
    这种问题,就是多个水龙头,多个不同接水时间的人去接水,先接水时间短的人先去接水后面的再是接水慢的人
    //顾客等待的队列为client,提供服务的窗口s个
    double greedy(vector client, int s)
    {
      //服务窗口的顾客等待时间
      vector service(s+1, 0);
      //服务窗口顾客等待时间的总和
      vector sum(s+1, 0);
      //顾客的数量
      int n = client.size();
      //按顾客的服务时间升序排序
      sort(client.begin(), client.end());
    }
    也就总结这些东西了,其实还有很多东西还没有理解。

猜你喜欢

转载自blog.csdn.net/ProgreamA/article/details/88542938