zoukankan      html  css  js  c++  java
  • 算法模板:贪心

    1. 贪心:

      • 原理:局部选择最优解,当前选择对后续不产生影响

      • 基本思路:

        ① 建立数学模型来描述问题

        ② 分解为若干子问题

        ③ 依序对每一个子问题求最优解(下一个包含上一个的最优解)

        ④ 把所有子问题的局部最优解合并为原问题的一个解

      1. 活动安排问题

        • 会场安排活动:即按活动的结束时间排序,让剩余时间最大化,安排更多的活动

        • 代码:

          bool cmp1(node a, node b)
          {
              return a.end < b.end ;      //结束时间从小到大排序
          }
          
          sort(Num+1, Num+n+1, cmp1);
          
          for(int i=2; i<=n; i++)
              {
                  if(Num[i].begin >= Num[1].end)
                  {
                      Num[1].end = Num[i].end ; //更新结束时间 
                      count++;            
                  }       
              }
          
        • 活动安排会场:按活动的开始时间排序,如果时间冲突则加一个会场

        • 代码:

          bool cmp(node a,node b) {
              return a.start < b.start;
          }
          
          sort(Num,Num+n,cmp);
          
          b[0]=p[0].end ;
          sum = 1;
          for(i=1; i<n; i++)
          {
             for(j=0; j<sum; j++)
             {
                if(b[j] <= p[i].start )//找到房间,更新结束时间
                {
                   b[j]=p[i].end ;
                   break;
                }      
             }
             if(j==sum)//未找到房间,更新结束时间
             {
                b[sum]=p[i].end ;
                ++sum;
             }
          }
          
      2. 找零钱问题:

        • 问题描述:找钱,有几种不同面值的货币,求最少使用多少张

        • 策略:优先使用面值大的货币

        • 代码:

          int num = 4; //4种 
          int m[] = {25,10,5,1}; //面值
          int target = 99; //要找
          int count[4]; //记录每种面值需多少
          for(int i=0; i<num; i++) {
          	count[i] = target / m[i];
          	target = target % m[i];
          }
          
      3. 背包问题:

        • 问题描述:一堆物品,在负重允许下取最高价值
        • 策略:
          1. 优先选择价值最大者(value)
          2. 优先选择重量最小者(weight)
          3. 优先选择性价比最高者(value / weight)
        • 以上三者无具体情况无法确定究竟是哪种策略最优
      4. 均分纸牌:

        • 问题描述:N堆纸牌,从任一堆上去任意张到临边牌堆,最少多少次使牌堆一样多

        • 策略:每次都考虑从i牌堆取来a[i]-avg张牌使a[i+1]达到均值

        • 代码:

          for(int i=0; i<n-1; i++) {
              if(a[i] != avg ) {
                  int move = a[i] - avg;
                  a[i] -= move;
                  a[i+1] += move;
                  times ++;
              }
          }
          
  • 相关阅读:
    PHP 原型模式
    PHP 观察者模式
    PHP 策略模式
    PHP 适配器模式
    PHP static静态属性和静态方法
    PHP中this,self,parent三个关键字
    PHP 单例模式
    git修改账号密码-命令行
    微信开发SDK推荐
    Java并发编程:线程池的使用
  • 原文地址:https://www.cnblogs.com/syisyuan/p/13708441.html
Copyright © 2011-2022 走看看