假设我们要使用独特的望远镜观察星星。列出在天空中可见的每颗恒星。每颗恒星都出现在某个时间窗口内,有可能有多颗恒星重叠,因此该小组为每颗恒星分配了一个值,表示需要观察它。
输入内容包含一个时间间隔列表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-竞争程序的网站)
答案 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.