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

    题目
    首先设(f_{i,j})表示在第(i)个村庄修了(j)个基站的答案。
    那么(f_{i,j}=c_i+minlimits_{kin[j-1,i)}(f_{k,j-1}+cost_{k,i}))
    其中(cost_{k,i})表示只在(k,i)修基站的情况下((k,i))中未被覆盖的村庄的(w)之和。
    我们发现(j)可以滚掉,把枚举(j)放到外面一层来,就有(f_i=c_i+minlimits_{kin[j-1,i)}(f_k+cost_{k,i}))
    这东西直接算肯定没法做,我们分析一下每个部分本质上是什么。
    首先我们观察(f_i)的计算式,(c_i)是完全不变的,可以无视掉。
    (f_k+cost_{k,i})这个东西,在固定一个(i)时它是一个与(k)有关的变量。
    那么一个比较自然的想法就是,每次将(i-1)扩展至(i)时,我们先求出(f_i)(在(i)位置修一个基站),然后对(cost)进行更新(在(i)位置不修基站)。
    对于一个村庄(i),我们先预处理(st_i,ed_i),如果在([st_i,ed_i])内没有哪个村庄修了基站的话这个村庄(i)就需要被赔偿。
    因为(i)位置不修基站,所以我们需要处理所有(ed_p=i)(p)村庄对(cost)的影响。
    (p)村庄需要被赔偿等价于上一个基站在([1,st_p-1]),也就是从(f_1sim f_{st_p-1})转移过来的需要加上(w_p),即把(cost_{1,i}sim cost_{st_p-1,i})加上(w_p)
    那么我们用线段树维护(f_k+cost_{k,i}),支持区间加和区间求最小值即可。

    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<algorithm>
    #define pb push_back
    #define ls p<<1
    #define rs p<<1|1
    #define mid ((l+r)>>1)
    const int N=20007,inf=0x3f3f3f3f;
    using namespace std;
    int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
    int max(int a,int b){return a>b? a:b;}
    int min(int a,int b){return a<b? a:b;}
    int d[N],c[N],s[N],w[N],f[N],st[N],ed[N],val[N<<2],tag[N<<2];
    vector<int>edp[N];
    void pushup(int p){val[p]=min(val[ls],val[rs]);}
    void add(int p,int v){val[p]+=v,tag[p]+=v;}
    void pushdown(int p){add(ls,tag[p]),add(rs,tag[p]),tag[p]=0;}
    void build(int p,int l,int r)
    {
        tag[p]=0;
        if(l==r) return (void)(val[p]=f[l]);
        build(ls,l,mid),build(rs,mid+1,r),pushup(p);
    }
    void update(int p,int l,int r,int L,int R,int v)
    {
        if(L<=l&&r<=R) return (void)(tag[p]+=v,val[p]+=v);
        if(tag[p]) pushdown(p);
        if(L<=mid) update(ls,l,mid,L,R,v);
        if(R>mid) update(rs,mid+1,r,L,R,v);
        pushup(p);
    }
    int query(int p,int l,int r,int L,int R)
    {
        if(L<=l&&r<=R) return val[p];
        if(tag[p]) pushdown(p);
        return min((L<=mid? query(ls,l,mid,L,R):inf),(R>mid? query(rs,mid+1,r,L,R):inf));
    }
    int main()
    {
        int n=read(),k=read()+1,i,j,sum,ans;
        for(i=2;i<=n;++i) d[i]=read();
        for(i=1;i<=n;++i) c[i]=read();
        for(i=1;i<=n;++i) s[i]=read();
        for(i=1;i<=n;++i) w[i]=read();
        ++n,d[n]=w[n]=inf;
        for(i=1;i<=n;++i) st[i]=lower_bound(d+1,d+n+1,d[i]-s[i])-d,ed[i]=upper_bound(d+1,d+n+1,d[i]+s[i])-d-1,edp[ed[i]].pb(i);
        for(i=1,sum=0;i<=n;++i)
        {
    	f[i]=sum+c[i];
    	for(int p:edp[i]) sum+=w[p];
        }
        ans=f[n];
        for(i=2;i<=k;++i)
        {
    	build(1,1,n);
    	for(j=1;j<=n;++j)
    	{
    	    f[j]=(j>i-1? query(1,1,n,i-1,j-1):0)+c[j];
    	    for(int p:edp[j]) if(st[p]>1) update(1,1,n,1,st[p]-1,w[p]);
    	}
    	ans=min(ans,f[n]);
        }
        printf("%d",ans);
    }
    
  • 相关阅读:
    CSS+HTML+flexible.js+rem实现屏幕缩放适配概念原理解释
    《写给程序员的Python教程》阅读随笔---python禅学(Zen_of_python)
    Python使用sql语句对mysql数据库多条件模糊查询
    request.json和request.form
    Python的flask接收前台的ajax的post数据和get数据
    Echarts世界地图和网页表格数据交互联动
    团队项目简介
    ajax和flask路由传json格式数据出现undefined和object错误
    世界疫情div界面搭建初步
    解决element-ui DateTimePicker 默认日期格式化问题
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11765391.html
Copyright © 2011-2022 走看看