⑴ OJ贪心算法,活动安排,求大神解答
按结束时间从小到大排序,之后从开始贪心即可
⑵ 使用贪心算法解决活动安排问题时使用什么优先贪心选择策略
贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择来得到。
就是说,你需要证明当前问题可以通过选择最好的那个元素(比如01背包,总能够通过选择当前重量最小的物品来得到最优解)来解决问题
证明:(每一步所做的贪心选择最终导致问题的整体最优解)
//基本思路:考察一个问题的最优解,证明可修改该最优解,使得其从贪心选择开始,然后用数学归纳法证明每一步都可以通过贪心选择得到最优解
1,假定首选元素不是贪心选择所要的元素,证明将首元素替换成贪心选择所需元素,依然得到最优解;
2,数学归纳法证明每一步均可通过贪心选择得到最优解
⑶ C语言程序问题——活动安排问题
题目出得不严密,题目要求是“计算安排的活动最多时会场使用时间”,但当“安排的活动最多”有多种安排方式,题目中却没说输出这多种方式中的哪一种的会场使用时间。例如 :当有3项活动要安排,开始时间和结束时间分别是1 2、3 5、4 5,这时可以安排第一项和第二项活动,也可以安排第一项和第三项活动,前者的会场使用时间是5,后者是4,这时是输出4还是5,题目中没用指出。先假设测试数据不会出现上述情况,则利用贪心算法求解活动安排问题是一种最常用的方法:#include<stdio.h>
#include<stdlib.h>
struct activity
{
int start;
int end;
}act[8501];
int comp(const void *p, const void *q)
{
struct activity *a=(struct activity *)p;
struct activity *b=(struct activity *)q;
return a->end-b->end;
}
int main()
{
int i,k,res,e;
while(scanf("%d",&k)!=EOF)
{
for(i=0;i<k;i++) scanf("%d%d",&act[i].start,&act[i].end);
qsort(act,k,sizeof(act[0]),comp);
res=act[0].end-act[0].start+1;
e=act[0].end;
for(i=1;i<k;i++)
{
if(act[i].start>e)
{
res+=act[i].end-act[i].start+1;
e=act[i].end;
}
}
printf("%d\n",res);
}
return 0;
}
⑷ 贪心算法活动安排问题中....按结束时间的非减序排序是什么意思
就是升序排序
⑸ 算法怎么学
贪心算法的定义:
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
解题的一般步骤是:
1.建立数学模型来描述问题;
2.把求解的问题分成若干个子问题;
3.对每一子问题求解,得到子问题的局部最优解;
4.把子问题的局部最优解合成原来问题的一个解。
如果大家比较了解动态规划,就会发现它们之间的相似之处。最优解问题大部分都可以拆分成一个个的子问题,把解空间的遍历视作对子问题树的遍历,则以某种形式对树整个的遍历一遍就可以求出最优解,大部分情况下这是不可行的。贪心算法和动态规划本质上是对子问题树的一种修剪,两种算法要求问题都具有的一个性质就是子问题最优性(组成最优解的每一个子问题的解,对于这个子问题本身肯定也是最优的)。动态规划方法代表了这一类问题的一般解法,我们自底向上构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以其中的最优值作为自身的值,其它的值舍弃。而贪心算法是动态规划方法的一个特例,可以证明每一个子树的根的值不取决于下面叶子的值,而只取决于当前问题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节点的值。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只需要自根开始,选择最优的路,一直走到底就可以了。
话不多说,我们来看几个具体的例子慢慢理解它:
1.活动选择问题
这是《算法导论》上的例子,也是一个非常经典的问题。有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。例如下图所示的活动集合S,其中各项活动按照结束时间单调递增排序。
关于贪心算法的基础知识就简要介绍到这里,希望能作为大家继续深入学习的基础。
⑹ 贪婪算法指的是什么
贪心算法是指在对问题进行求解时,在每-步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的。
贪婪算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果。
例题、区间问题
问题描述:有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与。
即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。限制条件:1<=n<=1000001<=si<=ti,=109样例:输入51 2 4 6 83 5 7 9 10输出3(选择工作1, 3, 5)。
⑺ 贪心算法的会场安排问题
查找有冲突的活动,将有冲突的放到第二个会场。
继续查找有冲突的活动,放到第三个会场。
就是贪心么。先按第一会场排,然后排第二会场、……
不知道是不是最优解。暂时还想不到反例。
⑻ 请问数钱的贪婪算法怎样确保得到最优解
贪婪算法:总是作出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅是在某种意义上的局部最优解。
(注:贪婪算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题它能产生整体最优解。但其解必然是最优解的很好近似解。
基本思路:——从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止
实现该算法的过程:
从问题的某一初始解出发;
while 能朝给定总目标前进一步 do
求出可行解的一个解元素;
由所有解元素组合成问题的一个可行解;
基本要素:
1、 贪婪选择性质:所求问题的整体最优解可以通过一系列局部最优的选择,即贪婪选择来达到。(与动态规划的主要区别)
采用自顶向下,以迭代的方式作出相继的贪婪选择,每作一次贪婪选择就将所求问题简化为一个规模更小的子问题。
对于一个具体问题,要确定它是否具有贪婪选择的性质,我们必须证明每一步所作的贪婪选择最终导致问题的最优解。通常可以首先证明问题的一个整体最优解,是从贪婪选择开始的,而且作了贪婪选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法证明,通过每一步作贪婪选择,最终可得到问题的一个整体最优解。
2、最优子结构性质:包含子问题的最优解
1、 设有n个活动的安排,其中每个活动都要求使用同一资源,如演讲会场,而在同一时间只允许一个活动使用这一资源。每个活动都有使用的起始时间和结束时间。问:如何安排可以使这间会场的使用率最高。
活动 起始时间 结束时间
1 1 4
2 3 5
3 0 6
4 5 7
5 3 8
6 5 9
7 6 10
8 8 11
9 8 12
10 2 13
11 12 14
算法:一开始选择活动1,然后依次检查活动一i是否与当前已选择的所有活动相容,若相容则活动加入到已选择的活动集合中,否则不选择活动i,而继续检查下一活动的相容性。即:活动i的开始时间不早于最近加入的活动j的结束时间。
Prodere plan;
Begin
n:=length[e];
a {1};
j:=1;
for i:=2 to n do
if s[i]>=f[j] then
begin a a∪{i};
j:=i;
end
end;
例1 [找零钱] 一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪婪准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。
假设需要找给小孩6 7美分,首先入选的是两枚2 5美分的硬币,第三枚入选的不能是2 5美分的硬币,否则硬币的选择将不可行(零钱总数超过6 7美分),第三枚应选择1 0美分的硬币,然后是5美分的,最后加入两个1美分的硬币。
贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少(见练习1)。
⑼ 贪心算法 活动安排问题
这道题的贪心算法比较容易理解,我就不多说明了,只是提到一下算法思路1、建立数学模型描述问题。我在这里将时间理解成一条直线,上面有若干个点,可能是某些活动的起始时间点,或终止时间点。在具体一下,如果编程来实现的话,将时间抽象成链表数组,数组下标代表其实时间,该下标对应的链表代表在这个时间起始的活动都有哪些,具体参照程序注释。2、问题分解。为了安排更多的活动,那么每次选取占用时间最少的活动就好。那么从一开始就选取结束时间最早的,然后寻找在这个时间点上起始的活动,以此类推就可以找出贪心解。程序代码:#include<stdio.h>
struct inode //自定义的结构体
{
int end; //表示结束时间
inode *next; //指向下一个节点的指针
};int main()
{
inode start[10001],*pt;
int a,b,i,num=0; //num负责计数,i控制循环,a,b输入时候使用
for(i=0;i<10001;i++) //初始化
{
start[i].next=NULL;
}
while(scanf("%d %d",&a,&b)) //输入并建立数据结构
{
if(a==0&&b==0) break;
pt=new inode; //创建新的节点,然后将该节点插入相应的位置
pt->end=b;
pt->next=start[a].next;
start[a].next=pt;
}
i=0;
while(i<10001) //进行贪心算法,i表示当前时间
{
if(start[i].next==NULL)
{
i++; //该时间无活动开始
}
else
{
int temp=10001; //临时变量,存储该链表中最早的终止时间
for(pt=start[i].next;pt!=NULL;pt=pt->next)
{
if(pt->end<temp)
{
temp=pt->end;
}
}
i=temp; //将当前时间设置成前一子问题的终止时间
num++;
}
}
printf("%d\n",num); //打印结果
return 0;
}代码并不一定是最快速的,但是可以求出贪心解,如果你做的是ACM编程题目,不保证能AC注释我尽力写了,希望对你有帮助。
⑽ 采用贪心算法进行安排。对算法的时间和空间复杂度进行分析
时间主要是 排序用时了,快速排序 一般是 o(n*logn)
空间 复杂度基本上是 0(1)