题解:
简单dp,可以有两种解法,时间复杂度分别是O(N) || O(M^2),都需要对interval排序预处理。
O(N):
对时间轴进行dp,当时间与某个interval的起始时间重合时,对该interval的终止时间dp。
O(M^2):
对每个interval与在他之前满足条件的interval叠加。
注意休息时间R,可以在输入时进行预处理,如果+R不超过N就+=R,如果超过N就直接赋值为N。
代码实现:
O(N)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N = 1000010;
const int MAX_M = 1010;
struct Interval{
int stime,etime;
int efficiency;
friend bool operator < (Interval a,Interval b){
if( a.stime == b.stime ){
return a.etime < b.etime;
}
return a.stime < b.stime;
}
};
int res;
int N,M,R;
int dp[MAX_N];
Interval Lis[MAX_M];
int main()
{
res = 0;
scanf("%d%d%d",&N,&M,&R);
for( int i = 0; i < M; i++ ){
scanf("%d%d%d",&Lis[i].stime,&Lis[i].etime,&Lis[i].efficiency);
if( Lis[i].etime+R < N ){
Lis[i].etime += R;
}
else{
Lis[i].etime = N;
}
}
int pos = 0;
sort(Lis,Lis+M);
memset(dp,0,sizeof(dp));
for( int i = 0; i <= N; i++ ){
if( i != 0 ){
dp[i] = max(dp[i],dp[i-1]);
}
while( i == Lis[pos].stime ){
dp[Lis[pos].etime] = max(dp[Lis[pos].etime],dp[i]+Lis[pos].efficiency);
pos++;
}
}
printf("%d\n",dp[N]);
return 0;
}
O(M^2)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N = 1000010;
const int MAX_M = 1010;
struct Interval{
int stime,etime;
int efficiency;
friend bool operator < (Interval a,Interval b){
if( a.stime == b.stime ){
return a.etime < b.etime;
}
return a.stime < b.stime;
}
};
int res;
int N,M,R;
int dp[MAX_M];
Interval Lis[MAX_M];
int main()
{
res = 0;
scanf("%d%d%d",&N,&M,&R);
for( int i = 0; i < M; i++ ){
scanf("%d%d%d",&Lis[i].stime,&Lis[i].etime,&Lis[i].efficiency);
if( Lis[i].etime+R < N ){
Lis[i].etime += R;
}
else{
Lis[i].etime = N;
}
}
sort(Lis,Lis+M);
memset(dp,0,sizeof(dp));
for( int i = 0; i < M; i++ ){
dp[i] = Lis[i].efficiency;
for( int j = 0; j < i; j++ ){
if( Lis[j].etime <= Lis[i].stime ){
dp[i] = max(dp[i],dp[j]+Lis[i].efficiency);
}
}
res = max(res,dp[i]);
}
printf("%d\n",res);
return 0;
}