版权声明:本文为博主原创文章,未经博主允许不得转载,除非先点了赞。 https://blog.csdn.net/A_Bright_CH/article/details/83108520
题意
奶牛Bessie在0~N时间段产奶。农夫约翰有M个时间段可以挤奶,时间段f,t内Bessie能挤到的牛奶量e。奶牛产奶后需要休息R小时才能继续下一次产奶,求Bessie最大的挤奶量。
如果在(si,ti)时刻挤奶,那么休息完的时间是si+r,即下一次可以挤奶的最早时间是(si+r,...)。
题解
DP+树状数组
设f[i]表示在第i小时结束挤奶时收获的最大奶量。有如下DP方程
可以用树状数组解决这个问题。真高兴,第一道自己YY出来的树状数组优化DP,尽管很水。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000010,maxm=1010;
int n,m,r,ans=0;
struct U{int s,t,c;}a[maxm];
bool cmp(U u1,U u2){return u1.s<u2.s;}
int mx[maxn];
void change(int x,int c)
{
for(;x<=n;x+=x&-x) mx[x]=max(mx[x],c);
}
int findmax(int x)
{
int re=-(1<<30);
for(;x>=1;x-=x&-x) re=max(re,mx[x]);
return re;
}
int main()
{
scanf("%d%d%d",&n,&m,&r);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].c);
a[i].s++;a[i].t++;
}n++;
sort(a+1,a+m+1,cmp);
for(int i=1;i<=m;i++)
{
int f=findmax(max(a[i].s-r,1))+a[i].c;
ans=max(ans,f);
change(a[i].t,f);
}
printf("%d\n",ans);
return 0;
}