贪心算法的C语言实现与运用详解

贪心算法

所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。贪心算法的基本思路如下:

1.建立数学模型来描述问题。

2.把求解的问题分成若干个子问题。

3.对每一子问题求解,得到子问题的局部最优解。

4.把子问题的解局部最优解合成原来解问题的一个解。

实现该算法的过程:

从问题的某一初始解出发;

while 能朝给定总目标前进一步

do 求出可行解的一个解元素;

由所有解元素组合成问题的一个可行解;

#include "stdio.h"
void main()
{
   int act[11][3]={{1,1,4},{2,3,5},{3,0,6},{4,5,7},{6,5,9},
   {7,6,10},{8,8,11},{9,8,12},{10,2,13},{11,12,14}};
   greedy(act,11);
   getch();
}
int greedy(int *act,int n)
{
   int i,j,no;
   j=0;
   printf("Selected activities:/n");
   no=0;
   printf("Act.%2d: Start time %3d, finish time %3d/n", act[no],act[no+1],act[no+2]);
  for(i=1;i<n;i++)
  {
    no=i*3;
    if(act[no+1]>=act[j*3+2])
       {
         j=i;
         printf("Act.%2d: Start time %3d, finish time %3d/n",    act[no],act[no+1],act[no+2]);
       }
    }
 }

 例题

题目描述: 
    又到毕业季,很多大公司来学校招聘,招聘会分散在不同时间段,小明想知道自己最多能完整的参加多少个招聘会(参加一个招聘会的时候不能中断或离开)。 
    输入: 
    第一行n,有n个招聘会,接下来n行每行两个整数表示起止时间,由从招聘会第一天0点开始的小时数表示。 
    n <= 1000 。 
    输出: 
    最多参加的招聘会个数。 
    样例输入: 
    3 
    9 10 
    10 20 
    8 15 
    样例输出: 
    2

活动选择问题
概述
这个问题是对几个相互竞争的招聘会活动进行调度,它们都要求以独占的方式使用某一公共资源(小明)。调度的目标是找出一个最大的相互兼容的活动集合。这里是有一个需要使用某一资源(小明)的n个活动组成的集合S={a1,a2,...,an}.该资源一次只能被一个活动占用。每个活动ai有开始时间si和结束时间fi,且0<=si<fi<无穷。一旦被选择后,活动ai就占据了区间[si,fi].如果区间[si,fi]和[sj,fj]互不重叠,称活动ai和aj是兼容的。活动选择问题就是要选择出一个由互相兼容的问题组成的最大子集合。
将所有的活动按照结束时间升序排列

定理
对于任意非空子问题Sij,设am是Sij中具有最早结束时间的活动:
fm=min{fk:ak属于Sij}
那么,
1)活动am在Sij的某最大兼容活动子集中被使用
2)子问题Sim为空,所以选择am将使子问题Smj为唯一可能非空的子问题

ac代码

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h> 

  struct join
  {
    int begin;
    int end;
  }; 

  int compare(const void *a, const void *b); 

  int main()
  {
    int i, n, k;
    struct join joins[1001], temp[1001]; 

    while(scanf("%d", &n) != EOF)
    {
      for(i = 0; i < n; i ++)
      {
        scanf("%d %d", &joins[i].begin, &joins[i].end);
      } 

      qsort(joins, n, sizeof(joins[0]), compare); 

      k = 0;
      temp[k] = joins[0];
      for(i = 1; i < n; i ++)
      {
        if(joins[i].begin >= temp[k].end)
          temp[++ k] = joins[i];
      }
      printf("%d\n", k + 1);
    } 

    return 0;
  } 

  int compare(const void *a, const void *b)
  {
    const struct join *p = a;
    const struct join *q = b; 

    return p->end - q->end;
  }

/**************************************************************
        Problem: 1463
        User: wangzhengyi
        Language: C
        Result: Accepted
        Time:10 ms
        Memory:904 kb
    ****************************************************************/

(0)

相关推荐

  • C语言对堆排序一个算法思路和实现代码

    算法思想简单描述: 堆排序是一种树形选择排序,是对直接选择排序的有效改进. 堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆.在这里只讨论满足前者条件的堆. 由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项.完全二叉树可以很直观地表示堆的结构.堆顶为根,其它为左子树.右子树. 初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的

  • 常用排序算法的C语言版实现示例整理

    所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来.其确切定义如下: 输入:n个记录R1,R2,-,Rn,其相应的关键字分别为K1,K2,-,Kn. 输出:Ril,Ri2,-,Rin,使得Ki1≤Ki2≤-≤Kin.(或Ki1≥Ki2≥-≥Kin).     排序的时间开销可用算法执行中的数据比较次数与数据移动次数来衡量.基本的排序算法有如下几种:交换排序(冒泡排序.快速排序).选择排序(直接选择排序.堆排序).插入排序(直接插入排序.希尔排序).归并排序.分配排序(基数排

  • 常用Hash算法(C语言的简单实现)

    如下所示: #include "GeneralHashFunctions.h" unsigned int RSHash(char* str, unsigned int len) { unsigned int b = 378551; unsigned int a = 63689; unsigned int hash = 0; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash = hash * a + (*str);

  • floyd算法实现思路及实例代码

    正如我们所知道的,Floyd算法用于求最短路径.Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3). Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B.所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,

  • 常用的C语言排序算法(两种)

    1. 要求输入10个整数,从大到小排序输出 输入:2 0 3 -4 8 9 5 1 7 6 输出:9 8 7 6 5 3 2 1 0 -4 解决方法:选择排序法 实现代码如下: #include <stdio.h> int main(int argc, const char * argv[]) { int num[10],i,j,k,l,temp; //用一个数组保存输入的数据 for(i=0;i<=9;i++) { scanf("%d",&num[i]);

  • 贪心算法的C语言实现与运用详解

    贪心算法 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解.贪心算法的基本思路如下: 1.建立数学模型来描述问题. 2.把求解的问题分成若干个子问题. 3.对每一子问题求解,得到子问题的局部最优解. 4.把子问题的解局部最优解合成原来解问题的一个解. 实现该算法的过程: 从问题的某一初始解出发:

  • JVM内存管理之JAVA语言的内存管理详解

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓狂的内存溢出和泄露的问题. 可怕的事情还不只如此,有些使用其它语言开发的程序员,给JAVA程序员扣上了一个"不懂内存"的帽子,这着实有点让人难以接受.毕竟JAVA当中没有malloc和delete.没有析构函数.没有指针,刚开始接触JAVA的程序员们又怎么可能接触内存这一部分呢,更何况有不

  • C语言动态规划之背包问题详解

    01背包问题 给定n种物品,和一个容量为C的背包,物品i的重量是w[i],其价值为v[i].问如何选择装入背包的物品,使得装入背包中的总价值最大?(面对每个武平,只能有选择拿取或者不拿两种选择,不能选择装入某物品的一部分,也不能装入物品多次) 声明一个数组f[n][c]的二维数组,f[i][j]表示在面对第i件物品,且背包容量为j时所能获得的最大价值. 根据题目要求进行打表查找相关的边界和规律 根据打表列写相关的状态转移方程 用程序实现状态转移方程 真题演练: 一个旅行者有一个最多能装M公斤的背

  • C语言之快速排序案例详解

    快速排序:是对冒泡排序算法的一种改进. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 例如有一个数字序列: 5 0 1 6 8 2 3 4 9 7 对其进行快速排序变为:0 1 2 3 4 5 6 7 8 9 思路如下:首先将要排序的序列的首个数字5定位比较数,这是一个参考对象! 然后的方法很简单:分别从序列的两端进行比较.先

  • C语言数据结构之堆排序详解

    目录 1.堆的概念及结构 2.堆的实现 2.1堆的向下调整算法 2.2堆的向上调整算法 2.3建堆(数组) 2.4堆排序 2.5堆排序的时间复杂度 1.堆的概念及结构 如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树(二叉树具体概念参见——二叉树详解)的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为小堆(或大

  • 基于JS脚本语言的基础语法详解

    JS脚本语言的基础语法:输出语法  alert("警告!");  confirm("确定吗?");   prompt("请输入密码");为弱类型语言: 开始时要嵌入JS代码:<script type="text/javascript"></script>: 关于写程序是需注意的基本语法: 1.所有的字符全都是英文半角的: 2.大部分情况下每条语句结束后要加分号: 3.每一块代码结束后加换行:4.程序前呼

  • js-FCC算法-No repeats please字符串的全排列(详解)

    把一个字符串中的字符重新排列生成新的字符串,返回新生成的字符串里没有连续重复字符的字符串个数.连续重复只以单个字符为准 例如, aab 应该返回 2 因为它总共有6中排列 (aab, aab, aba, aba, baa, baa),但是只有两个 (aba and aba)没有连续重复的字符 (在本例中是 a). 从网上资料获得了一些思路,我的代码: function permAlone(str) { var arr=str.split(""); var perarr=[]; var

  • Linux 下C语言连接mysql实例详解

    Linux 下C语言连接mysql实例详解 第一步: 安装mysql, 参考:http://www.jb51.net/article/39190.htm 第二步: 安装mysql.h函数库 sudo apt-get install libmysqlclient-dev 执行之后就可以看到/usr/include/MySQL目录了 然后开始我们的链接. 首先看我的数据库 mysql> show databases; +--------------------+ | Database | +----

  • C语言文件复制实例详解

    C语言文件复制实例详解 文件复制,在Linux中,将生成的read.o 重新文件拷贝一份复制到ReadCopy.o中,并且更改ReadCopy.o文件的操作权限.使其能够正常运行. 实例代码: #include <stdio.h> int main(){ FILE *r_file = fopen ("read.o","rb"); FILE *w_file = fopen ("ReadCopy.o","w"); ch

  • C++语言实现hash表详解及实例代码

    C++语言实现hash表详解 概要: hash表,有时候也被称为散列表.个人认为,hash表是介于链表和二叉树之间的一种中间结构.链表使用十分方便,但是数据查找十分麻烦:二叉树中的数据严格有序,但是这是以多一个指针作为代价的结果.hash表既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便. 打个比方来说,所有的数据就好像许许多多的书本.如果这些书本是一本一本堆起来的,就好像链表或者线性表一样,整个数据会显得非常的无序和凌乱,在你找到自己需要的书之前,你要经历许多的查询过程:而如果

随机推荐