BZOJ 1642: [Usaco2007 Nov]Milking Time 挤奶时间 (dp,类似LIS)

Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 667  Solved: 389 [Submit][Status][Discuss]

Description

贝茜是一只非常努力工作的奶牛,她总是专注于提高自己的产量。为了产更多的奶,她预计好了接下来的N (1 ≤ N ≤ 1,000,000)个小时,标记为0..N-1。 Farmer John 计划好了 M (1 ≤ M ≤ 1,000) 个可以挤奶的时间段。每个时间段有一个开始时间(0 ≤ 开始时间 ≤ N), 和一个结束时间 (开始时间 < 结束时间 ≤ N), 和一个产量 (1 ≤ 产量 ≤ 1,000,000) 表示可以从贝茜挤奶的数量。Farmer John 从分别从开始时间挤奶,到结束时间为止。每次挤奶必须使用整个时间段。 但即使是贝茜也有她的产量限制。每次挤奶以后,她必须休息 R (1 ≤ R ≤ N) 个小时才能下次挤奶。给定Farmer John 计划的时间段,请你算出在 N 个小时内,最大的挤奶的量。

Input

第1行三个整数N,M,R.接下来M行,每行三个整数Si,Ei,Pi.

Output

 最大产奶量.

Sample Input

12 4 2 1 2 8 10 12 19 3 6 24 7 10 31

Sample Output

43

HINT

注意:结束时间不挤奶

思路:这题很像LIS啊。。由于每次结束要休息R的时间,所以把结束时间+R就好。

然后按照开始时间排序。

dp[i]表示前i个任务安排最大的挤奶量。

初始化dp[i] = a[i].val

转移的时候 dp[i] = max(dp[i],dp[j]+a[i].val)  (j<i&&a[j].r<=a[i].l)

/* ***********************************************
Author :111qqz
Created Time :2016年04月10日 星期日 01时50分11秒
File Name :code/bzoj/1642.cpp
************************************************ */
 1#include <cstdio>
 2#include <cstring>
 3#include <iostream>
 4#include <algorithm>
 5#include <vector>
 6#include <queue>
 7#include <set>
 8#include <map>
 9#include <string>
10#include <cmath>
11#include <cstdlib>
12#include <ctime>
13#define fst first
14#define sec second
15#define lson l,m,rt<<1
16#define rson m+1,r,rt<<1|1
17#define ms(a,x) memset(a,x,sizeof(a))
18typedef long long LL;
19#define pi pair < int ,int >
20#define MP make_pair
 1using namespace std;
 2const double eps = 1E-8;
 3const int dx4[4]={1,0,0,-1};
 4const int dy4[4]={0,-1,1,0};
 5const int inf = 0x3f3f3f3f;
 6const int N=1E3+7;
 7struct node
 8{
 9    int l,r;
10    int val;
1    bool operator < (node b)const
2    {
3	if (l==b.l) return r<b.r;
4	return l<b.l;
5    }	
6}a[N];
7int n,m,R;
8int sum;
9int dp[N];
1int main()
2{
3	#ifndef  ONLINE_JUDGE 
4	freopen("code/in.txt","r",stdin);
5  #endif
1	scanf("%d %d %d",&n,&m,&R);   //有点LIS的感觉...
2	for ( int i = 1 ; i <= m ; i++)
3	{
4	    scanf("%d %d %d",&a[i].l,&a[i].r,&a[i].val);
5	    a[i].r += R;
6	    a[i].r = min(a[i].r,n);
7	}
8	sort(a+1,a+m+1);
	ms(dp,0);
	for ( int i = 1 ;i  <= m ; i++) dp[i] =  a[i].val;
 1//	for ( int i = 1 ; i <= m ; i++) cout<<dp[i]<<" ";
 2//	cout<<endl;
 3	int ans = -1;
 4	for ( int i = 2 ; i <= m ; i++)
 5	{
 6	    for ( int j = 1 ; j < i ; j++)
 7	    {
 8		if (a[j].r<=a[i].l)
 9		{
10		    dp[i] = max(dp[i],dp[j]+a[i].val);
11		}
12	    }
13//	    for ( int j = 1 ; j <= m ; j++) cout<<dp[j]<<" ";
14//	    cout<<endl;
15	    ans = max(ans,dp[i]);
16	}
	printf("%d\n",ans);
1  #ifndef ONLINE_JUDGE  
2  fclose(stdin);
3  #endif
4    return 0;
5}