Luo Gu $ P2605 \ [ZJOI2010] $ base station siting tree line optimization $ dp $

Positive Solutions: $ dp $ optimization segment tree

Report problem solving:

Portal $ QwQ $

A sad ,,, originally wanted to test questions, I made the question a very sophisticated plane, then $ dp $ speaking today when they were talking about the $ kk $

DP consider violence $ $? Is located $ f_ {i, j} $ J represents a group selected of $ $ $ I $ base stations is the minimum cost, there is $ f_ {i, j} = min (f_ {k, j} + cost (k, i)) + c_i $, $ this will cost $ $ [k + 1, i-1] of the compensation of all base stations and between $.

Found that the $ cost $ seek not good? So thinking outside the box, each finished in the decision to enter the election will not vote for $ x $ of $ x $ stage after the move is complete thing (because it is, $ j $ in the outer loop $ i $ in the inner layer, each also will choose a base station, the base station will be the decision-making after the first $ j $ a $ x $ after the election decision $ j $ th election $ x $, $ x $ that the first base station will not be picked $ QwQ $), then the $ [1, x] within the range of $ all $ x $ election because it does not lead to an increase in the cost plus

Thus a pretreatment to $ st_ {i} $ a and $ ed_ {i} $ array, let $ I represents the number range covered by the base station $, then each time all $ ed_ {i} = x $ point . to find out, but found when a selected point in time during the $ [st_ {i}, ed_ {i} -1] $ range would still not matter, so long as the $ f _ {[1, st [i] - 1], j} + = w_i $

Now becomes a minimum interval of plus range queries, like tree line maintenance, $ over $

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rc register char
#define rb register bool
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
#define lb(x) lower_bound(d+1,d+1+n,x)-d

const int N=20000+10,inf=0x3f3f3f3f;
int n,K,d[N],c[N],s[N],w[N],st[N],ed[N],tr[N<<2],tag[N<<2],ed_cnt,head[N],f[N],as;
struct edg{int to,nxt;}edge[N];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il void ad(ri x,ri y){edge[++ed_cnt]=(edg){x,head[y]};head[y]=ed_cnt;}
void build(ri nw,ri l,ri r)
{
    tag[nw]=0;if(l==r)return void(tr[nw]=f[l]);
    ri mid=(l+r)>>1;build(nw<<1,l,mid);build(nw<<1|1,mid+1,r);
    tr[nw]=min(tr[nw<<1],tr[nw<<1|1]);
}
il void pushdown(ri nw)
{
    if(!tag[nw])return;
    tag[nw<<1]+=tag[nw];tag[nw<<1|1]+=tag[nw];tr[nw<<1]+=tag[nw];tr[nw<<1|1]+=tag[nw];tag[nw]=0;
}
void add(ri nw,ri l,ri r,ri to_l,ri to_r,ri dat)
{
    if(to_l<=l && r<=to_r){tr[nw]+=dat;tag[nw]+=dat;return;}//return void(tr[nw]+=dat,tag[nw]+=dat);
    pushdown(nw);ri mid=(l+r)>>1;
    if(mid>=to_l)add(nw<<1,l,mid,to_l,to_r,dat);if(mid<to_r)add(nw<<1|1,mid+1,r,to_l,to_r,dat);
    tr[nw]=min(tr[nw<<1],tr[nw<<1|1]);
}
int query(ri nw,ri l,ri r,ri to_l,ri to_r)
{
//    printf("nw=%d l=%d r=%d to_l=%d to_r=%d\n",nw,l,r,to_l,to_r);
    if(to_l<=l && r<=to_r)return tr[nw];
    pushdown(nw);ri mid=(l+r)>>1,ret=inf;
    if(mid>=to_l)ret=query(nw<<1,l,mid,to_l,to_r);if(mid<to_r)ret=min(ret,query(nw<<1|1,mid+1,r,to_l,to_r));
//    printf("[%d,%d]:%d\n")
    return ret;
}

int main()
{
//    freopen("2605.in","r",stdin);//freopen("2605.out","w",stdout);
    n=read();K=read()+1;rp(i,2,n)d[i]=read();rp(i,1,n)c[i]=read();rp(i,1,n)s[i]=read();rp(i,1,n)w[i]=read();++n;d[n]=w[n]=inf;
    rp(i,1,n){st[i]=lb(d[i]-s[i]);ed[i]=lb(d[i]+s[i]);if(d[ed[i]]>d[i]+s[i])--ed[i];ad(i,ed[i]);}
    ri ret=0;rp(i,1,n){f[i]=ret+c[i];e(j,i)ret+=w[t(j)];}as=f[n];
    rp(i,2,K)
    {
        build(1,1,n);
        rp(j,1,n)
        {
            f[j]=(j>i-1?query(1,1,n,i-1,j-1):0)+c[j];//printf("f[%d]=%d=%d+%d\n",j,f[j],j>i-1?query(1,1,n,1,j-1):0,c[j]);
            e(k,j)if(st[t(k)]>1)add(1,1,n,1,st[t(k)]-1,w[t(k)]);
        }
        as=min(as,f[n]);
    }
    printf("%d\n",as);
    return 0;
}
View Code

Guess you like

Origin www.cnblogs.com/lqsukida/p/11577575.html