题目描述
Farmer John 正在考虑改变他给奶牛挤奶的时候分配牛奶桶的方式。他认为这最终能使得他使用数量更少的桶,然而他不清楚具体是多少,请帮助他!
Farmer John 有 N 头奶牛,方便起见编号为 1…N。
第 i 头奶牛需要从时刻 si 到时刻 ti 之间挤奶,并且挤奶过程中需要用到 bi 个桶。
多头奶牛可能在同一时刻都在挤奶;每个桶在每个时刻只能供一头奶牛使用。
也就是说,第 i 头奶牛在时刻 si 到时刻 ti 之间挤奶时,如果用到了某个桶,则该桶在这段时间不能被其他奶牛使用。
当然,这个桶在这段时间之外可以被其他奶牛所使用。
为了简化他的工作,FJ 保证在任一时刻,至多只有一头奶牛开始或是结束挤奶(也就是说,所有的 si 和 ti 各不相同)。
FJ 有一个储藏室,里面有依次编号为 1、2、3、…… 的桶。
在他的挤奶策略中,当某一头奶牛(比如说,奶牛 i)开始挤奶(在时刻 si),FJ 就跑到储藏室取出编号最小的 bi 个桶分配给第 i 头奶牛用来挤奶。
请求出 FJ 需要在储藏室中存放多少个桶才能使得他能够顺利地给所有奶牛挤奶。
输入格式
输入的第一行包含 N。以下 N 行,每行描述了一头奶牛,包含三个空格分隔的数 si,ti,bi。
其中 si 和 ti 均为 1…1000 之间的整数,bi 为 1…10 之间的整数。
输出格式
输出一个整数,为 FJ 需要的桶的数量。数据范围
1≤N≤100
样例
输入样例:
3
4 10 1
8 13 3
2 6 2
输出样例:
4
样例解释
在这个例子中,FJ 需要 4 个桶:他用桶 1 和桶 2 来给奶牛 3 挤奶(从时刻 2 开始)。
他用桶 3 给奶牛 1 挤奶(从时刻 4 开始)。
当奶牛 2 在时刻 8 开始挤奶时,桶 1 和桶 2 可以再次利用,然而桶 3 不可以,
所以他会使用桶 1、桶 2 和桶 4。
思路一:
这题考的是拆分的本质
可以发现拆分其实表现某段区间内的点的分布,
加上前缀和求得正好是区间点的数值
之后取最大值就可以得到本题答案
时间复杂度 O(n+m)
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int t,n;
int res[N],sum[N];
int main()
{
cin>>t;
while(t--)
{
int l,r,d;
cin>>l>>r>>d;
res[l]+=d;
res[r+1]-=d;
}
for(int i=1;i<=1010;i++)
{
sum[i]=sum[i-1]+res[i];
n=max(n,sum[i]);
}
return cout<<n,0;
}
思路二:
当然这个题其实就是求某个点的最多的桶子数目,可以枚举每个区间,然后将区间中的每个点加上需要的桶子数目,然后找到整个区间中的最大值。
这样求也是可以的;
只不过时间复杂度变为O(nm)
时间复杂度 O(nm)
java 代码
import java.io.*;
import java.util.*;
public class Main {
static int n;
static int[] a;
public static void main(String args[]) {
Scanner cin=new Scanner(System.in);
n=cin.nextInt();
a=new int[1050];
for(int i=1;i<=n;i++)
{
int l=cin.nextInt(),r=cin.nextInt(),d=cin.nextInt();
for(int j=l;j<=r;j++)
a[j]+=d;
}
int ans=0;
for(int i=1;i<=1010;i++)
if(a[i]>ans)ans=a[i];
System.out.println(ans);
}
}
欢迎留言点赞