zoukankan      html  css  js  c++  java
  • [ZJOI2010]基站选址

    题目描述

    有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di。需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci。如果在距离第i个村庄不超过Si的范围内建立了一个通讯基站,那么就村庄被基站覆盖了。如果第i个村庄没有被覆盖,则需要向他们补偿,费用为Wi。现在的问题是,选择基站的位置,使得总费用最小。

    输入输出格式

    输入格式:

    输入文件的第一行包含两个整数N,K,含义如上所述。

    第二行包含N-1个整数,分别表示D2,D3,…,DN ,这N-1个数是递增的。

    第三行包含N个整数,表示C1,C2,…CN。

    第四行包含N个整数,表示S1,S2,…,SN。

    第五行包含N个整数,表示W1,W2,…,WN。

    输出格式:

    输出文件中仅包含一个整数,表示最小的总费用。

    输入输出样例

    输入样例#1:
    3 2
    1 2
    2 3 2
    1 1 0
    10 20 30
    输出样例#1:
    4

    说明

    40%的数据中,N<=500;

    100%的数据中,K<=N,K<=100,N<=20,000,Di<=1000000000,Ci<=10000,Si<=1000000000,Wi<=10000。

    首先可以推出暴力的DP方程:f[i][j]表示在第i个位置建第j个基站不考虑i后面的最小费用.
    转移就是f[i][j]=min(f[p][j-1]+不能覆盖的位置的补偿.)(p<i)
    很明显j这一维可以滚掉.
    那么现在复杂度的瓶颈在与后面的那一坨.
    然后想不出来了,有一篇题解讲的很清楚:
    我们假设f(j)目前已经计算完了,现在想要计算f(j+1)
    我们转移每一层(1~K)时,建立一棵线段树,对于每个点k维护f(k)+cost(k,j)(注意这个东西是随着j的增长而变化的)
    观察一下方程,可以发现,原方程中每个f(k),1<=k<=j-1是不随着j的增长而变化的,变化的只有cost(k,i)
    是什么引起了cost(k,i)的变化呢?cost(k,i)变化到cost(k,i+1),说明有些本来能被i位置建立的一座基站覆盖到的村子,因为i->i+1而覆盖不到了,需要给他们补偿
    那么我们可以预处理出每个村庄的sted,分别代表在村庄i()侧建立基站仍能覆盖到村庄i的最远村庄位置,这个可以二分求出,O(nlogn)
    每次转移完f(i)时,将ed(x)=i的所有x,将[1,st[x]-1]这段区间在线段树中
    加上w[x]即可.

    主要思想就是动态维护后面的那一坨,找出每次会变的量和一直不变的量,然后想办法用线段树维护.


     1 #include<bits/stdc++.h>
     2 #define inf 2000000000
     3 #define maxn 20010
     4 #define ls o*2
     5 #define rs o*2+1
     6 #define mi int mid=(l+r)>>1
     7 using namespace std;
     8 int C[maxn],S[maxn],W[maxn],dis[maxn],st[maxn],ed[maxn],f[maxn],n,k;
     9 vector<int>vec[maxn];
    10 int b[maxn*4],lazy[maxn*4];
    11 inline void prepare(){
    12   scanf("%d%d",&n,&k);
    13   for(int i=2;i<=n;i++)scanf("%d",&dis[i]);
    14   for(int i=1;i<=n;i++)scanf("%d",&C[i]);
    15   for(int i=1;i<=n;i++)scanf("%d",&S[i]);
    16   for(int i=1;i<=n;i++)scanf("%d",&W[i]);
    17   dis[++n]=inf/2;W[n]=inf/2;++k;
    18   for(int i=1;i<=n;i++){
    19     st[i]=lower_bound(dis+1,dis+n+1,dis[i]-S[i])-dis;
    20     ed[i]=upper_bound(dis+1,dis+n+1,dis[i]+S[i])-dis -1;
    21     vec[ed[i]].push_back(i);
    22   }
    23 }
    24 inline void down(int o){
    25   lazy[ls]+=lazy[o],lazy[rs]+=lazy[o];
    26   b[ls]+=lazy[o],b[rs]+=lazy[o];
    27   lazy[o]=0;
    28 }
    29 void build(int o,int l,int r){
    30   lazy[o]=0;
    31   if(l==r){b[o]=f[l];return;}
    32   mi;
    33   build(ls,l,mid),build(rs,mid+1,r);
    34   b[o]=min(b[ls],b[rs]);
    35 }
    36 int query(int o,int l,int r,int u,int v){
    37   if(l!=r)down(o);
    38   if(v<u) return 0;
    39   if(l>v || r<u) return inf;
    40   if(l>=u && r<=v) return b[o];
    41   mi;
    42   if(v<=mid) return query(ls,l,mid,u,v);
    43   else if(u>mid) return query(rs,mid+1,r,u,v);
    44   else return min(query(ls,l,mid,u,mid),query(rs,mid+1,r,mid+1,v));
    45 }
    46 void add(int o,int l,int r,int u,int v,int val){
    47   if(l!=r)down(o);
    48   if(v<u) return;
    49   if(l>v || r<u) return;
    50   if(l>=u && r<=v){b[o]+=val;lazy[o]+=val;return;}
    51   mi;
    52   if(v<=mid) add(ls,l,mid,u,v,val);
    53   else if(u>mid) add(rs,mid+1,r,u,v,val);
    54   else add(ls,l,mid,u,mid,val),add(rs,mid+1,r,mid+1,v,val);
    55   b[o]=min(b[ls],b[rs]);
    56 }
    57 int main(){
    58   prepare();
    59   int ans=inf,tmp=0;
    60   for(int i=1;i<=n;i++){
    61     f[i]=tmp+C[i];
    62     for(int p=0;p<vec[i].size();p++)
    63       tmp+=W[vec[i][p]];
    64   }
    65   ans=f[n];
    66   for(int j=2;j<=k;j++){
    67     
    68     build(1,1,n);
    69     for(int i=1;i<=n;i++){
    70       f[i]=query(1,1,n,1,i-1)+C[i];
    71       for(int p=0;p<vec[i].size();p++){
    72     int x=vec[i][p];
    73     add(1,1,n,1,st[x]-1,W[x]);
    74       }
    75     }
    76     ans=min(ans,f[n]);
    77   }
    78   printf("%d",ans);
    79   return 0;
    80 }
  • 相关阅读:
    js中调用ocx控件
    web.xml配置文件中<async-supported>true</async-supported>报错的解决方案
    shiro整合spring配置
    shiro中的reaml理解及实现机制
    oracle数据库安装
    关于身份认证、角色认证和权限认证的shiro-web例子
    创建maven管理的web项目
    hadoop Hive 的建表 和导入导出及索引视图
    hadoop Mapreduce组件介绍
    hadoop hive组件介绍及常用cli命令
  • 原文地址:https://www.cnblogs.com/pantakill/p/7502661.html
Copyright © 2011-2022 走看看