线段树优化dp

数组f[i][j]表示在前i个村庄内,第j个基站建在i处的最小费用

根据交线牛逼法和王鹤松式可得方程

f[i][j]=min(f[k][j−1]+cost(k,i))

cost(k,i)表示第i~k个村庄之间没有被基站覆盖的村庄所需的赔偿费用,计算费用的复杂度为O(n)

利用二分查找预处理每个位置的需求范围bef[i],beh[i]

之后就是利用线段树维护f[]+cost()的最小值,区间查询区间更新

当beh[x]=i,若i不建造,则加cost(可能存在很多x,前向星或vector存储)

Code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#define ls(k) k<<1
#define rs(k) k<<1|1
using namespace std;
const int N=20010,K=110;
int dis[N],s[N],w[N],c[N],f[N];
int n,m,bef[N],beh[N];
int tot=0,to[N<<1],head[N<<1],nxt[N<<1];
int mn[N<<2],lz[N<<2];
void Add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void up(int k)
{
mn[k]=min(mn[ls(k)],mn[rs(k)]);
}
void build(int k,int l,int r)
{
lz[k]=0;
if(l==r)
{
mn[k]=f[l];
return ;
}
int mid=l+r>>1;
build(ls(k),l,mid);
build(rs(k),mid+1,r);
up(k);
}
void down(int k)
{
lz[ls(k)]+=lz[k];
lz[rs(k)]+=lz[k];
mn[ls(k)]+=lz[k];
mn[rs(k)]+=lz[k];
lz[k]=0;
}
int query(int k,int l,int r,int L,int R)
{
if(L>R)return 0x3f3f3f3f;
if(L<=l&&R>=r)return mn[k];
int mid=l+r>>1;
if(lz[k])down(k);
int res=0x3f3f3f3f;
if(L<=mid)res=min(res,query(ls(k),l,mid,L,R));
if(mid<R)res=min(res,query(rs(k),mid+1,r,L,R));
return res;
}
void change(int k,int l,int r,int L,int R,int vl)
{
if(L>R)return ;
if(L<=l&&R>=r)
{
lz[k]+=vl;
mn[k]+=vl;
return ;
}
if(lz[k])down(k);
int mid=l+r>>1;
if(L<=mid)change(ls(k),l,mid,L,R,vl);
if(R>mid)change(rs(k),mid+1,r,L,R,vl);
up(k);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++)scanf("%d",&dis[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]);
n++,m++;
dis[n]=w[n]=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
bef[i]=lower_bound(dis+1,dis+n+1,dis[i]-s[i])-dis;
beh[i]=lower_bound(dis+1,dis+n+1,dis[i]+s[i])-dis;
if(dis[beh[i]]>dis[i]+s[i])beh[i]--;
Add(beh[i],i);
}
int now=0;
for(int j=1;j<=n;j++)
{
f[j]=now+c[j];
for(int i=head[j];i;i=nxt[i])now+=w[to[i]];
}
int ans=f[n];
for(int i=2;i<=m;i++)
{
build(1,1,n);
for(int j=1;j<=n;j++)
{
f[j]=query(1,1,n,1,j-1)+c[j];
for(int p=head[j];p;p=nxt[p])
change(1,1,n,1,bef[to[p]]-1,w[to[p]]);
}
ans=min(ans,f[n]);
}
cout<<ans<<endl;
return 0;
}

题解 P2605 【[ZJOI2010]基站选址】(From luoguBlog)的更多相关文章

  1. 【题解】Luogu P2605 [ZJOI2010]基站选址

    原题传送门:P2604 [ZJOI2010]基站选址 看一眼题目,变知道这题一定是dp 设f[i][j]表示在第i个村庄修建第j个基站且不考虑i+1~n个村庄的最小费用 可以得出f[i][j] = M ...

  2. luogu P2605 [ZJOI2010]基站选址 线段树优化dp

    LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...

  3. P2605 [ZJOI2010]基站选址

    题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄不超过Si的范 ...

  4. luogu P2605 [ZJOI2010]基站选址

    luogu 先考虑朴素dp,设\(f_{i,j}\)表示在第\(i\)个村庄放了基站,一共放了\(j\)次,且只考虑前面村庄影响的答案.这里可以把\(j\)放在外面枚举,然后从\(f_{k,j-1}( ...

  5. 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$

    正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ...

  6. 题解 [ZJOI2010]基站选址

    题解 [ZJOI2010]基站选址 题面 解析 首先考虑一个暴力的DP, 设\(f[i][k]\)表示第\(k\)个基站设在第\(i\)个村庄,且不考虑后面的村庄的最小费用. 那么有\(f[i][k] ...

  7. 【LG2605】[ZJOI2010]基站选址

    [LG2605][ZJOI2010]基站选址 题面 洛谷 题解 先考虑一下暴力怎么写,设\(f_{i,j}\)表示当前\(dp\)到\(i\),且强制选\(i\),目前共放置\(j\)个的方案数. 那 ...

  8. [ZJOI2010]基站选址,线段树优化DP

    G. base 基站选址 内存限制:128 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较   题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离 ...

  9. bzoj 1835: [ZJOI2010]基站选址

    Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...

随机推荐

  1. ansible使用jinja2管理配置文件以及jinja2语法简介

    一.Jinja2介绍 Jinja2是基于python的模板引擎,功能比较类似于PHP的smarty,J2ee的Freemarker和velocity.它能完全支持unicode,并具有集成的沙箱执行环 ...

  2. Tomcat 7源码学习笔记 -9 tomcat重启后session仍然保留

    使用Tomcat 7缺省的配置,tomcat关闭后重新启动,发现原来的session没有被删掉,用原来的request获取session仍然可以取到.但是并没有配置session持久化. 原因如下: ...

  3. 络谷 P1363 幻想迷宫

    P1363 幻想迷宫 题目描述 背景 Background (喵星人LHX和WD同心协力击退了汪星人的入侵,不幸的是,汪星人撤退之前给它们制造了一片幻象迷宫.) WD:呜呜,肿么办啊…… LHX:mo ...

  4. window.parent与window.opener、window.showModalDialog的区别 opener和showModalDialog刷新父页面的方法

    项目中使用案例: 父窗体 <s:form namespace="/forexagent" id="listSearchForm" name="t ...

  5. Axis2中使用wsdl2java.bat生成客户端代码

    1 准备环境 (1)下载Axis2的zip包axis2-1.5.5-bin.zip,并解压. 官方网址:http://ws.apache.org/axis2/ (2)设置环境变量(我的电脑->属 ...

  6. N天学习一个linux命令之netstat

    用途 打印网络连接,路由表,网卡信息,假连接,组播成员信息 用法 1 显示网络连接信息 netstat [address_family_options] [--tcp|-t] [--udp|-u] [ ...

  7. natural join 以及 v$statname , v$sessstat

    oracle natural join是一个比较方便的用法.如果两个表的某些字段名称相同,类型相同,natural join就会把他们做等值连接.比如下面我们知道这两个视图的结构如下: SQL> ...

  8. ural 1468

    写了好久,不知道为什么不过,也不清楚到底卡在哪里... 只好看别人的代码,感觉除了HASH不一样外,倒没什么特别之处.同时参考那论文写的.. http://blog.csdn.net/jyysc201 ...

  9. 基数排序之多keyword排序运用队列

    源码例如以下: #include <stdlib.h> #include <stdio.h> typedef struct QUEUEnode* link; struct QU ...

  10. 【Java集合源代码剖析】Hashtable源代码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简单介绍 Hashtable相同是基于哈希表实现的,相同每 ...