[ZJOI2010]基站选址(线段树优化dp)
Posted owencodeisking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ZJOI2010]基站选址(线段树优化dp)相关的知识,希望对你有一定的参考价值。
坑待填。
(Code Below:)
#include <bits/stdc++.h>
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
const int maxn=20000+10;
const int inf=0x3f3f3f3f;
int n,k,d[maxn],c[maxn],s[maxn],w[maxn],f[maxn],st[maxn],ed[maxn],sum[maxn<<2],lazy[maxn<<2];
vector<int> q[maxn];
inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return (f==1)?x:-x;
}
inline void pushup(int rt){
sum[rt]=min(sum[lson],sum[rson]);
}
inline void pushdown(int rt){
if(lazy[rt]){
sum[lson]+=lazy[rt];sum[rson]+=lazy[rt];
lazy[lson]+=lazy[rt];lazy[rson]+=lazy[rt];
lazy[rt]=0;
}
}
void build(int l,int r,int rt){
lazy[rt]=0;
if(l == r){
sum[rt]=f[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(rt);
}
void update(int L,int R,int C,int l,int r,int rt){
if(L <= l && r <= R){
sum[rt]+=C;lazy[rt]+=C;
return ;
}
pushdown(rt);
int mid=(l+r)>>1;
if(L <= mid) update(L,R,C,l,mid,lson);
if(R > mid) update(L,R,C,mid+1,r,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L > R) return 0;
if(L <= l && r <= R){
return sum[rt];
}
pushdown(rt);
int mid=(l+r)>>1,ans=inf;
if(L <= mid) ans=min(ans,query(L,R,l,mid,lson));
if(R > mid) ans=min(ans,query(L,R,mid+1,r,rson));
return ans;
}
int main()
{
n=read(),k=read();
for(int i=2;i<=n;i++) d[i]=read();
for(int i=1;i<=n;i++) c[i]=read();
for(int i=1;i<=n;i++) s[i]=read();
for(int i=1;i<=n;i++) w[i]=read();
d[++n]=inf;w[n]=inf;k++;
for(int i=1;i<=n;i++){
st[i]=lower_bound(d+1,d+n+1,d[i]-s[i])-d;
ed[i]=lower_bound(d+1,d+n+1,d[i]+s[i])-d;
if(d[ed[i]]>d[i]+s[i]) ed[i]--;
q[ed[i]].push_back(i);
}
int x,ans,val=0;
for(int i=1;i<=n;i++){
f[i]=val+c[i];
for(int j=0;j<q[i].size();j++){
x=q[i][j];val+=w[x];
}
}
ans=f[n];
for(int t=2;t<=k;t++){
build(1,n,1);
for(int i=1;i<=n;i++){
f[i]=query(1,i-1,1,n,1)+c[i];
for(int j=0;j<q[i].size();j++){
x=q[i][j];
if(st[x]>1) update(1,st[x]-1,w[x],1,n,1);
}
}
ans=min(ans,f[n]);
}
printf("%d
",ans);
return 0;
}
以上是关于[ZJOI2010]基站选址(线段树优化dp)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1835 [ZJOI2010]base 基站选址(DP+线段树)