题目大意:
有点懒,直接截图吧。
solution:
这题赛场上把$n^{2}$DP打了出来,谁知需要初始化,调了好几个小时,自闭了。$n^{2}$DP显然,前后各扫一遍,在此基础上,讲讲正解吧。
一道简单dp.我们直觉是数据结构优化dp,这里用了线段树.具体实现方法:先将高度离散化,然后以高度为下标构造线段树,其上的值为该高度的最大$dp$值.至于$cost$的处理,我们只需要在每次状态转移完成之后,将$[1,h[i]]$处的$dat$值全减去$cost$即可.然后更新$h[i]$处的$dp$值。
code:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<map> #define R register #define next kdjadskfj #define debug puts("mlg") using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; inline ll read(); inline void write(ll x); inline void writeln(ll x); inline void writesp(ll x); ll n; ll lsh[1000000],p[1000000],c[1000000],h[1000000]; ll q; ll f[1000000][2]; ll ans=0; ll dat[1000000][2],lazy[1000000][2]; inline void pushdown(ll rt,ll l,ll r,bool type){ if(lazy[rt][type]==0) return; dat[rt<<1][type]+=lazy[rt][type]; dat[rt<<1|1][type]+=lazy[rt][type]; lazy[rt<<1][type]+=lazy[rt][type]; lazy[rt<<1|1][type]+=lazy[rt][type]; lazy[rt][type]=0; } inline void change(ll rt,ll l,ll r,ll u,ll v,ll k,bool type){ if(u<=l&&r<=v){dat[rt][type]+=k;lazy[rt][type]+=k;return;} pushdown(rt,l,r,type); ll mid=(l+r)>>1; if(u<=mid) change(rt<<1,l,mid,u,v,k,type); if(v>mid) change(rt<<1|1,mid+1,r,u,v,k,type); dat[rt][type]=max(dat[rt<<1][type],dat[rt<<1|1][type]); } inline void update(ll rt,ll l,ll r,ll k,ll goal,bool type){ pushdown(rt,l,r,type); if(l==r){dat[rt][type]=max(dat[rt][type],goal);return;} ll mid=(l+r)>>1; if(k<=mid) update(rt<<1,l,mid,k,goal,type); else update(rt<<1|1,mid+1,r,k,goal,type); dat[rt][type]=max(dat[rt<<1][type],dat[rt<<1|1][type]); } inline ll query(ll rt,ll l,ll r,ll u,ll v,bool type){ pushdown(rt,l,r,type); if(u<=l&&r<=v) return dat[rt][type]; ll ans=-((ull)1<<63),mid=(l+r)>>1; if(u<=mid) ans=max(ans,query(rt<<1,l,mid,u,v,type)); if(v>mid) ans=max(ans,query(rt<<1|1,mid+1,r,u,v,type)); return ans; } int main(){ // freopen("herbary.in","r",stdin); // freopen("herbary.out","w",stdout); n=read(); for(R ll i=1;i<=n;i++){ lsh[i]=h[i]=read();p[i]=read();c[i]=read(); } sort(lsh+1,lsh+n+1); q=unique(lsh+1,lsh+n+1)-lsh-1; for(R ll i=1;i<=n;i++){ h[i]=lower_bound(lsh+1,lsh+q+1,h[i])-lsh; } // for(R ll i=0;i<=(n<<2)+n;i++) dat[i][0]=dat[i][1]=-((ull)1<<63); for(R ll i=1;i<=n;i++){ f[i][0]=query(1,1,n,0,h[i],0)+p[i]; change(1,1,n,1,h[i],-c[i],0); update(1,1,n,h[i],f[i][0],0); } for(R ll i=n;i>=1;i--){ f[i][1]=query(1,1,n,0,h[i],1)+p[i]; change(1,1,n,1,h[i],-c[i],1); update(1,1,n,h[i],f[i][1],1); } for(R ll i=1;i<=n;i++) ans=max(ans,f[i][0]+f[i][1]-p[i]); // for(R ll i=1;i<=n;i++) writesp(f[i][0]);putchar(' '); // for(R ll i=1;i<=n;i++) writesp(f[i][1]);putchar(' '); writeln(ans); // for(R ll i=1;i<=n;i++){ // ll cost=0; // for(R ll j=i-1;j>=0;j--){ // if(h[j]>h[i]){cost+=c[j];continue;} // f[i][0]=max(f[i][0],f[j][0]-cost+p[i]); // } // } // for(R ll i=n;i>=1;i--){ // ll cost=0; // for(R ll j=i+1;j<=n+1;j++){ // if(h[j]>h[i]){cost+=c[j];continue;} // f[i][1]=max(f[i][1],f[j][1]-cost+p[i]); // } // } // for(R ll i=1;i<=n;i++) ans=max(ans,f[i][0]+f[i][1]-p[i]); // writeln(ans); } inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;} inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');} inline void writesp(ll x){write(x);putchar(' ');} inline void writeln(ll x){write(x);putchar(' ');}
$$衣带渐宽终不悔,为伊消得人憔悴。$$