[20200728NOIP提高组模拟T4]有趣的有趣的家庭菜园——自闭了

题目大意:

  有点懒,直接截图吧。[20200728NOIP提高组模拟T4]有趣的有趣的家庭菜园——自闭了_第1张图片

 

 

 [20200728NOIP提高组模拟T4]有趣的有趣的家庭菜园——自闭了_第2张图片

 

 [20200728NOIP提高组模拟T4]有趣的有趣的家庭菜园——自闭了_第3张图片

 

 solution:

  这题赛场上把$n^{2}$DP打了出来,谁知需要初始化,调了好几个小时,自闭了。$n^{2}$DP显然,前后各扫一遍,在此基础上,讲讲正解吧。

  一道简单dp.我们直觉是数据结构优化dp,这里用了线段树.具体实现方法:先将高度离散化,然后以高度为下标构造线段树,其上的值为该高度的最大$dp$值.至于$cost$的处理,我们只需要在每次状态转移完成之后,将$[1,h[i]]$处的$dat$值全减去$cost$即可.然后更新$h[i]$处的$dp$值。

code:

#include
#include
#include
#include
#include
#include
#include
#include
#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('\n');
//    for(R ll i=1;i<=n;i++) writesp(f[i][1]);putchar('\n');
    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('\n');}

 

$$衣带渐宽终不悔,为伊消得人憔悴。$$

你可能感兴趣的:([20200728NOIP提高组模拟T4]有趣的有趣的家庭菜园——自闭了)