望远镜计划

时间:2019-06-28 20:31:17

标签: c++ algorithm

假设我们要使用独特的望远镜观察星星。列出在天空中可见的每颗恒星。每颗恒星都出现在某个时间窗口内,有可能有多颗恒星重叠,因此该小组为每颗恒星分配了一个值,表示需要观察它。

输入内容包含一个时间间隔列表L,在该时间间隔中,可以观察到星星。每个区间i∈L由以下元素组成:

-开始时间S ii,之后将可以观察到恒星;

-结束时间Fii,之后将不再有星星;

-一个正整数D i i表示希望看到第i星。

为了满足看到第i颗星的需要,必须在从S i到F i(包括两端)的整个时间段内用望远镜进行观测。因此,如果时间间隔[Si,Fi]与时间间隔[Sj,Fj]相交,则无法同时观察到两个恒星i和j(即它们相互冲突)。给定天空中恒星可用性的时间间隔列表L,优化问题是以无冲突的方式安排观测,以使计划中包括的观测的总合意性最大化。标准输入

输入的第一行包含一个表示整数的正整数N。

以下i行中的每条1≤i≤N表示每颗恒星的开始(Si)和结束(Fi)时间以及看到该恒星的期望Di。

输出应为根据输入包含在时间表中的星星的合意性之和。

约束:

1≤N≤10 ^ 4

0≤Si,Fi≤10000

1≤Di≤5000

据我了解,在这种情况下,我们可以使用动态编程来使用众所周知的作业调度模型。

#include <iostream> 
#include<bits/stdc++.h> 
#include <algorithm> 
using namespace std; 

struct Star 
{ 
    int S, F, D; 
}; 


bool comparataor(Star s1, Star s2) 
{ 
    return (s1.F < s2.F); 
} 


int main() 

{  
    Star *arr;
   long long int N;
    bool found=0;


    cin >>N;
    arr=new Star[N];

    for(long long i=0;i<N;i++)
      cin >>arr[i].S>>arr[i].F>>arr[i].D; 


    sort(arr, arr+N, comparataor); 

    long long int *table = new long long int[N]; 
    table[0] = arr[0].D; 


    for (long long int i=1; i<N; i++) 
    { 
        long long int inclDesireability = arr[i].D; 
         long long  int l;
        found=0;
         long long int lo = 0, hi = i - 1; 

      while (lo <= hi && found==0) 
      { 
        long long int mid = (lo + hi) / 2; 
        if (arr[mid].F <= arr[i].S) 
        { 
            if (arr[mid + 1].F <= arr[i].S) 
                lo = mid + 1; 
            else
                {l= mid; 
                 found=1;
                }
        } 
        else
            hi = mid - 1; 
    }   

        if (found==1)
            inclDesireability += table[l]; 

        table[i] = max(inclDesireability, table[i-1]); 
    }



    cout<<table[N-1]<<endl; 
    delete[] table; 

    delete[] arr; 

   return 0;
} 

代码似乎运行良好,但是:

有些测试使此代码失败,但是我无法检测到原因,我只知道它失败了...

(来自csacademy-竞争程序的网站)

1 个答案:

答案 0 :(得分:1)

我首先想知道它们“相交”是什么意思。如果其中一个的结束时间与下一个的开始时间匹配,则您的latestNonConflict将包括一个冲突。但这应该是严格的<代替吗?

如果间隔为[1, 3], [4, 5], [2,6],也会发生什么。是否有可能在处理第二个时将第一个添加到inclDesireability中,然后[2, 6]处理该重叠间隔?

第二,您有一个O(N^2)算法。也许需要O(n log(n))?您可以使用堆结构来实现,请参见make_heap。这是主意。

我们有两种事件。间隔i开始,间隔i完成。可以先按时间订购它们,然后在完成之前开始。用伪代码:

best_schedule = empty schedule with desirability 0
for each interval i:
    make event_begin {is_start: True, interval: i, time: i.start, desirable: i.desirable, history: null}
    push event_begin onto events
make events into heap
while events not empty:
    event = pop_heap(events)
    if event.is_start:
        create event_finish {is_start: False, interval: i, time: i.start, desirable: best_schedule.desirable + i.desirable, history: best_schedule}
        events.push_heap(event_finish)
    else:
        if best_schedule.desirable < event.desirable:
            replace best_schedule with event.history followed by event.interval

best_schedule should be best possible.
相关问题