Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to schedule her next N (1 ≤ N ≤ 1,000,000) hours (conveniently labeled 0…N-1) so that she produces as much milk as possible.
Farmer John has a list of M (1 ≤ M ≤ 1,000) possibly overlapping intervals in which he is available for milking. Each interval i has a starting hour (0 ≤ starting_houri ≤ N), an ending hour (starting_houri < ending_houri ≤ N), and a corresponding efficiency (1 ≤ efficiencyi ≤ 1,000,000) which indicates how many gallons of milk that he can get out of Bessie in that interval. Farmer John starts and stops milking at the beginning of the starting hour and ending hour, respectively. When being milked, Bessie must be milked through an entire interval.
Even Bessie has her limitations, though. After being milked during any interval, she must rest R (1 ≤ R ≤ N) hours before she can start milking again. Given Farmer Johns list of intervals, determine the maximum amount of milk that Bessie can produce in the N hours.
Input
- Line 1: Three space-separated integers: N, M, and R
- Lines 2…M+1: Line i+1 describes FJ’s ith milking interval withthree space-separated integers: starting_houri , ending_houri , and efficiencyi
Output
- Line 1: The maximum number of gallons of milk that Bessie can product in the N hours
Sample Input
12 4 2
1 2 8
10 12 19
3 6 24
7 10 31
Sample Output
43
这个题目在本质上和背包问题是类似的,刚开始看到的时候,试图从时间的角度构造转移方程,,发现时间好像不太行,因为时间比较长,所以我就改变了思路,从时间间隔的角度构造转移方程,我设想这个问题其实就是要解决在这m 个时间间隔里找到一些时间间隔工作以获得maximum amount of milk ,对于每个时间间隔而言无非就是两种选择,工作或者不工作,
所以需要 dp[2][N]数组
dp[0][i] dp[0][i] 在第i个间隔不工作的情况下,从起始到i个时段能获得的最大牛奶,dp[1][i] 则为工作情况下最大量
si[N]; 标记dp[0][i] 在第i个阶段不工作情况下,奶牛最后工作后休息后的时间 记录这个是必要的,因为后面要判断时间
至于转移方程,有兴趣的小伙伴就看看代码吧
中间有个小细节有点坑,有兴趣的小伙伴看看代码注释
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <stack>
using namespace std;
#define N 1003
#define PI 3.14159265358979323
#define INF 0x3f3f3f3f
#define MOD 100000007
#define ll long long
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
int n,m,r;
struct intervel {
int st,ed,ef;
bool operator < ( const intervel &n1 ) const
{
if ( st==n1.st )
return ed<n1.ed;
return st<n1.st;
}
}a[N];
long long int dp[2][N]; // dp[0][i] 在第i个阶段不工作的情况下,从起始到i个时段能获得的最大牛奶,dp[1][i] 则为工作情况下最大量
int si[N]; // 标记dp[0][i] 在第i个阶段不工作情况下,奶牛最后工作后休息后的时间
//template < class T> void read ( T &x ){ char c;int sign=1;x=0;while ( c=getchar(),(c>'9'||c<'0')&&c!='-') ;if ( c=='-' ){sign=-1;}else x=c-'0';while ( c=getchar(),c<='9'&&c>='0' ){x=x*10+c-'0';}x=x*sign;}
int main ( )
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int i,j,k;
while ( cin>>n>>m>>r ){
for ( i=1;i<m+1;i++ ){
cin>>a[i].st >>a[i].ed >>a[i].ef ;
}
memset ( dp,0,sizeof(dp));
memset ( si,0,sizeof ( si));
sort ( a+1,a+1+m );
dp[1][1]=a[1].ef ;
for ( i=1;i<m+1;i++ ){
for ( j=1;j<i;j++ ){
if ( dp [0][i]<dp[1][j] ){
dp[0][i]=dp[1][j];
si[i]=a[j].ed +r;
}
if ( dp[0][i]<dp[0][j] ){
dp[0][i]=dp[0][j];
si[i]=si[j];
}
if ( si[j]<=a[i].st )
dp[1][i]=max ( dp[1][i],dp[0][j]+a[i].ef );
if ( a[j].ed +r<=a[i].st )
dp[1][i]=max ( dp[1][i],dp[1][j]+a[i].ef );
}
// cout<<dp[0][i]<<" "<<dp[1][i]<<endl;
}
cout<<max ( dp[0][m],dp[1][m])<<endl;
}
return 0;
}