文章目录
- 背包问题
- 活动安排问题
- 最优装载问题
- 删数问题
- 最优服务次序
贪心算法
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。过程:
建立数学模型来描述问题;
把求解的问题分成若干个子问题;
对每一子问题求解,得到子问题的局部最优解;
把子问题的解局部最优解合成原来解问题的一个解。
贪心与动态规划
联系:均由局部最优解来推导全局最优解,问题都具有最优子结构性质。
区别: 贪心只从当前的选择中,构造某种最优解。 动态规划综合考虑之前状态和当前的选择,决定当前状态的最优解。
背包问题

 首先计算每种物品单位重量的价值Pi = Vi / Wi
然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。
依此策略一直地进行下去,直到背包装满为止。
void Knapsack(int n,float M,float v[],float w[],float x[])
{  //n为物品总数,M为总容量
       Sort(n,v,w);
       int i;
       for (i=1;i<=n;i++) x[i]=0;
       float c=M;  // 剩余的容量
       for (i=1;i<=n;i++) {
          if (w[i]>c)  break;
          x[i]=1;
          c-=w[i];
          }
       if (i<=n) x[i]=c/w[i];
}
算法knapsack的主要计算时间在于将各种物品依其单位重量的价值从大到小排序。因此,算法的计算时间上界为O(nlogn)。
活动安排问题

template<class Type>
void GreedySelector(int n, Type s[], Type f[], bool A[])
{ // s数组存储活动起始时间,f数组存储活动结束时间,且各活动按结束时间已按非减序排列;A数组存储被选中的活动。
       A[1]=true;  // 选择活动1(结束最早的活动)
       int j=1; // j记录最近一次被选中的活动
       for (int i=2;i<=n;i++) {
          if (s[i]>=f[j]) { A[i]=true; j=i; }
          else A[i]=false;
          } // 每次总是选择具有最早完成时间的相容活动加入集合A中
}
最优装载问题


 
 
 
int  Loading(int x[ ],  int w[ ],  int C,  int n) // C为轮船剩余载重量
{    int *t= new  int[n+1];
     Sort(w, t, n);    
     for(i=1;i<=n; ++i)   x[i]=0;
     for(i=1;   w[t[i]]<=C&& i<=n;  ++i)
         {   x[t[i]]=1;  C -= w[t[i]];    }   
}
删数问题

 
 每次对正整数a进行“从最高位向最低位”的扫描,若当前位比后一位大,则删除当前位,后续的数字前移。
while (k > 0)
{
  int i = 0;
  while (i <= len && a[i] <= a[i+1])
      i++;            
  for (int j = i; j <= len; j++) 
      a[j] = a[j+1];
   k--;
   len--;
}

最优服务次序

 
 



















