洛谷2889 [USACO07NOV]擠奶的時間Milking Time(DP)(樹狀陣列)
阿新 • • 發佈:2018-11-11
題意
奶牛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; }