记录编号 382543 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2010] 基站选址 最终得分 100
用户昵称 Gravatarliu_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;
}