记录编号 |
382543 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[ZJOI 2010] 基站选址 |
最终得分 |
100 |
用户昵称 |
liu_runda |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
15.768 s |
提交时间 |
2017-03-14 07:42:54 |
内存使用 |
20.61 MiB |
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=20005;
int n;
struct node{
int sum;node* ch[2];
node(){}
node(int x){sum=x;ch[0]=ch[1]=0;}
}t[maxn*50],*root[maxn];int cnt=0;
node* newnode(int x){t[++cnt]=node(x);return t+cnt;}
void Insert(node* rt0,node* &rt,int l,int r,int k,int x){
rt=new node(rt0->sum+x);
if(l==r)return;
int mid=(l+r)>>1;
if(k<=mid){
Insert(rt0->ch[0],rt->ch[0],l,mid,k,x);
rt->ch[1]=rt0->ch[1];
}else{
Insert(rt0->ch[1],rt->ch[1],mid+1,r,k,x);
rt->ch[0]=rt0->ch[0];
}
}
int query(node* rt0,node* rt1,int l,int r,int ql,int qr){
if(ql>qr)return 0;
if(ql<=l&&r<=qr)return rt1->sum-rt0->sum;
int mid=(l+r)>>1,ans=0;
if(ql<=mid)ans+=query(rt0->ch[0],rt1->ch[0],l,mid,ql,qr);
if(qr>mid) ans+=query(rt0->ch[1],rt1->ch[1],mid+1,r,ql,qr);
return ans;
}
int f[105][maxn];
int d[maxn],c[maxn],s[maxn],w[maxn];
struct data{
int l,r,w;
//bool operator <(const data &B)const{return l<B.l;}
}range[maxn];
vector<data> D[maxn];
void solve(int j,int l,int r,int L,int R){
if(l>r)return;
int mid=(l+r)>>1,g=0;
f[j][mid]=0x7fffffff;
for(int i=L;i<=R&&i<mid;++i){
int tmp=f[j-1][i]+query(root[i],root[mid-1],1,n,i+1,mid-1)+c[mid];
if(tmp<f[j][mid]){
f[j][mid]=tmp;g=i;
}
}
solve(j,l,mid-1,L,g);solve(j,mid+1,r,g,R);
}
int main(){
freopen("base.in","r",stdin);
freopen("base.out","w",stdout);
int k;scanf("%d%d",&n,&k);
d[0]=0x80808080;d[n+1]=0x7fffffff;
for(int i=2;i<=n;++i)scanf("%d",&d[i]);
for(int i=1;i<=n;++i)scanf("%d",&c[i]);
for(int i=1;i<=n;++i)scanf("%d",&s[i]);
for(int i=1;i<=n;++i)scanf("%d",&w[i]);
for(int i=1;i<=n;++i){
range[i].l=lower_bound(d,d+n+2,d[i]-s[i])-d;range[i].r=upper_bound(d,d+n+2,d[i]+s[i])-d-1;
range[i].w=w[i];
D[range[i].l].push_back(range[i]);
}
root[0]=t+0;root[0]->ch[0]=root[0]->ch[1]=t+0;root[0]->sum=0;
for(int i=1;i<=n;++i){
root[i]=root[i-1];
for(vector<data>::iterator pt=D[i].begin();pt!=D[i].end();++pt){
Insert(root[i],root[i],1,n,pt->r,pt->w);
}
}
root[n+1]=root[n];
int ans=0;for(int i=1;i<=n;++i)ans+=w[i];
for(int i=1;i<=n;++i){
f[1][i]=query(root[0],root[i-1],1,n,1,i-1)+c[i];//printf("...%d\n",f[1][i]);
ans=min(ans,f[1][i]+query(root[i],root[n],1,n,i+1,n));//printf("%d\n",ans);
}//printf("%d\n",ans);
for(int j=2;j<=k;++j){
solve(j,1,n,0,n);
/*for(int i=1;i<=n;++i){
f[j][i]=0x7f7f7f7f;int g=0;
for(int l=1;l<i;++l){int old=f[j][i];
f[j][i]=min(f[j][i],f[j-1][l]+query(root[l],root[i-1],1,n,l+1,i-1)+c[i]);
if(f[j][i]<old)g=l;
}printf("%d ",g);
}*///printf("j%dans%d\n",j,ans);
for(int i=1;i<=n;++i)ans=min(ans,f[j][i]+query(root[i],root[n],1,n,i+1,n));
}
printf("%d\n",ans);
fclose(stdin);fclose(stdout);
// for(int i=1;i<=n;++i)printf("%d %d\n",range[i].l,range[i].r);
return 0;
}