Algorithm 找到我可以参加的课程的最大数量
我正试图找到一个最佳的(以复杂性的方式)算法,以获得我可以参加的课程的最大数量。我不在乎课程的总长度,也不在乎课程本身。这一切都是为了尽可能多地参加课程 给定两个数组S和E。S[i]包含课程的开始时间,E[i]包含相应的结束时间。数组已经按E排序了。因为我不是Flash,所以我不能参加第一个数组的结束时间等于下一个数组的开始时间的课程 下面是一个例子:Algorithm 找到我可以参加的课程的最大数量,algorithm,Algorithm,我正试图找到一个最佳的(以复杂性的方式)算法,以获得我可以参加的课程的最大数量。我不在乎课程的总长度,也不在乎课程本身。这一切都是为了尽可能多地参加课程 给定两个数组S和E。S[i]包含课程的开始时间,E[i]包含相应的结束时间。数组已经按E排序了。因为我不是Flash,所以我不能参加第一个数组的结束时间等于下一个数组的开始时间的课程 下面是一个例子: S = [ "2014-11-06 01:00:00", "2014-11-06 03:00:00", "2014-11
S = [
"2014-11-06 01:00:00",
"2014-11-06 03:00:00",
"2014-11-06 07:00:00",
"2014-11-06 09:00:00",
"2014-11-06 09:00:00"
]
E = [
"2014-11-06 05:00:00",
"2014-11-06 06:00:00",
"2014-11-06 08:00:00",
"2014-11-06 09:00:00",
"2014-11-06 10:00:00"
]
对于这些值,正确答案为3,因为我可以参加课程1、3和5(也可以进行其他组合)
提前感谢既然您评论说每门课程都需要全员参与,我想算法可以是这样的:
S1,S2,E1,E2,S3,E3。。。。SN,EN
如果我们不检查[3-N]部分,可以递归计算两次(带S1或不带S1)
核心思想
其思想是使用递归检查所有课程。蒂莫西·哈的回答解释了基本解决方案。为了清楚起见,我想起来:
//我假设S[]是按递增顺序排序的
//E[]是与S关联的结束时间:
//(从S[i]开始的课程在E[i]结束)
int findBestNumber(ADateType S[],ADateType E[],int n){
int i=n-1,k,res;
int*sol=NULL;
如果(!(sol=malloc(n*sizeof(int)))
返回-1;
memset(sol,0,sizeof(*sol));
溶胶[n-1]=1;
而(i-->0){
k=findMinIndex(E[i],S);
如果(k>=0)//k存在
sol[i]=max(1+sol[k],sol[i+1]);
否则//k不存在,我们将返回一个类似-1的值
sol[i]=sol[i+1];
}
res=sol[0];
免费(sol);
返回res;
}
findMinIndex(after,S)
搜索最小索引k,以便在≤ 由于调用此函数时,S
是排序的,因此这是一个简单的二进制搜索。在上面的例子中,如果找不到这样的索引,我认为我们从findMinIndex()
返回了一个负值
DP版本的空间和时间复杂性
在动态规划版本中,我们只是一步一步地计算中间结果,并且只计算一次。因此,这是O(n)。空间复杂度也是O(n),因为我们需要存储n个中间值
但请记住,我们必须按开始时间对课程进行排序!使用适当的排序算法(例如合并排序)的此操作为O(n.log(n))。因此,最终的时间复杂度为O(n.log(n))
奖励:一个可工作的C实现
注意:在再次阅读问题后,我注意到我无法选择与先前课程结束时间同时开始的课程…要排除这些课程,只需在
findMinIndex()中打开=
s
into
s倒数第二个元素对两个都是一样的。你必须坐满每门课吗?或者你可以只在场一点,然后转到另一门课吗?我必须在场,直到课程结束。我认为问题是NP完全问题,你必须通过所有的解决方案才能找到最好的解决方案。尽你最大的努力避免尝试您已经知道不可能的解决方案(子集不可能)您的问题与最大覆盖率问题类似()。贪婪算法似乎本质上是最大覆盖率的最佳多项式时间近似算法。这个问题可能很愚蠢,但我如何决定是否加入S1?第一步有两个选择:是否加入S1。使用递归计算到最后,如果S1的结果更大,则加入:-)我还想到了复杂性,因为它是一个线性扫描(两个并行),沿着课程队列,它应该是O(N)。丹尼尔,如果这个想法是正确的,你会把它转换成代码,对吗?@DanielFreudenberger,你怎么能达到O(N)下的复杂性呢?!你必须处理每一门课程才能做出决定,对吗?我同意,平均而言,但假设你能参与每一门课程,你最终会在每一门课程上执行二分法。当然,您可以使用动态规划降低时间复杂度:)感谢您提到动态规划。维基百科上有一整篇文章列出了“使用动态编程的算法”