BZOJ1835,LG2605 [ZJOI2010]基站选址
题意
有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为\(D_i\)
需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为\(C_i\)
如果在距离第i个村庄不超过\(S_i\)的范围内建立了一个通讯基站,那么就成它被覆盖了
如果第i个村庄没有被覆盖,则需要向他们补偿,费用为\(W_i\)
现在的问题是,选择基站的位置,使得总费用最小。
分析
朴素做法
用\(f(i,j)\)表示前\(i\)个村庄建了\(j\)个通讯站且第\(j\)个建在\(i\)处的最小代价,容易写出转移式
\]
其中\(cost(k,i)\)表示中间的补偿费用
然而这种做法时间是\(O(N \cdot K \cdot N)\),空间是\(O(N^2)\)的,不可行。
优化
如果我们外层枚举\(j\),里面枚举\(i\)呢?
很显然\(f\)的第二维和\(cost\)的第一维都可以省略。\(f\)可以用滚动,\(cost\)可以动态更新,因为变化元素的其实是有限(均摊\(O(1)\))的。
\]
由于一个村庄\(i\)被覆盖的条件是在距离第\(i\)个村庄不超过\(S_i\)的范围内建立了一个通讯基站,因此可以发现能覆盖一个村庄的基站位置应该是一个区间。
考虑第\(i\)个村庄对于的区间\([L,R]\),如果目前考虑的最后一个基站为\(R\),要转移到\(R+1\)
- 如果\(R\)处不建基站,那么对于相对\(R+1\)的上一个基站为\([1,L-1]\)的情况,都无法覆盖当前村庄,因此需要对\(cost\)的\([1,L-1]\)区间加\(W_i\)
- 如果\(R\)处建基站,那么相当于是在相对\(R+1\)的上一个基站为\([1,R-1]\)中选择一个代价最小的,相当于对之前\(f\)和\(cost\)的和区间查询最小值
用程序的语言来讲,我们用\(st_i\)和\(ed_i\)分别表示\(i\)最左端、最右端可以覆盖到\(i\)的通讯站位置,那么我们会发现当\(ed_x=i\)时,转移到\(i+1\)时\(x\)便覆盖不到了。
我们用线段树维护\(\min\{f(k)+cost(k)\}\),从\(f(i)\)变到\(f(i+1)\)时对于\(ed_x=i\)的\(x\),线段树中\([1,st_x−1]\)都加上\(W_x\)(加上补偿费用)即可
这样\(f\)就不用滚动了,\(cost\)也不用单独提出来。
外层循环枚举建站个数时每次重建线段树,复杂度\(O(K \cdot N \log N)\)
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=2e4+7;
#define lson (o<<1)
#define rson (o<<1|1)
int d[MAXN],c[MAXN],s[MAXN],w[MAXN];
int st[MAXN],ed[MAXN];
vector<int> g[MAXN];
int f[MAXN],ans;
struct SegTree
{
int minv[MAXN<<2],addv[MAXN<<2]; // edit 3
void pushup(int o)
{
minv[o]=min(minv[lson],minv[rson]);
}
void build(int o,int l,int r)
{
addv[o]=0; // edit 2
if(l==r)
{
minv[o]=f[l];
return;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(o);
}
void pushdown(int o)
{
if(addv[o])
{
minv[lson]+=addv[o],addv[lson]+=addv[o];
minv[rson]+=addv[o],addv[rson]+=addv[o];
addv[o]=0;
}
}
int qmin(int o,int l,int r,int ql,int qr)
{
if(ql>qr)
return 0;
// cerr<<"query "<<o<<" "<<l<<" "<<r<<" "<<ql<<" "<<qr<<endl;
if(ql<=l&&r<=qr)
return minv[o];
pushdown(o);
int mid=(l+r)>>1,ans=INF;
if(ql<=mid)
ans=min(ans,qmin(lson,l,mid,ql,qr));
if(qr>=mid+1)
ans=min(ans,qmin(rson,mid+1,r,ql,qr));
return ans;
}
void add(int o,int l,int r,int ql,int qr,int v)
{
if(ql>qr)
return;
// cerr<<"add "<<o<<" "<<l<<" "<<r<<" "<<ql<<" "<<qr<<" "<<v<<endl;
if(ql<=l&&r<=qr)
{
minv[o]+=v,addv[o]+=v;
return;
}
pushdown(o);
int mid=(l+r)>>1;
if(ql<=mid)
add(lson,l,mid,ql,qr,v);
if(qr>=mid+1)
add(rson,mid+1,r,ql,qr,v);
pushup(o);
}
}T;
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n,m;
read(n);read(m);
for(int i=2;i<=n;++i)
read(d[i]);
for(int i=1;i<=n;++i)
read(c[i]);
for(int i=1;i<=n;++i)
read(s[i]);
for(int i=1;i<=n;++i)
read(w[i]);
d[++n]=INF,w[n]=INF,++m;
for(int i=1;i<=n;++i)
{
st[i]=lower_bound(d+1,d+n+1,d[i]-s[i])-d;
ed[i]=lower_bound(d+1,d+n+1,d[i]+s[i])-d;
if(d[ed[i]]>d[i]+s[i])
--ed[i];
g[ed[i]].push_back(i);
}
int t=0;
for(int i=1;i<=n;++i)
{
f[i]=t+c[i];
for(int j=0;j<g[i].size();++j)
{
int x=g[i][j];
t+=w[x];
}
}
ans=f[n];
for(int i=2;i<=m;++i)
{
T.build(1,1,n); // edit 1
for(int j=1;j<=n;++j)
{
f[j]=T.qmin(1,1,n,1,j-1)+c[j];
for(int k=0;k<g[j].size();++k)
{
int x=g[j][k];
T.add(1,1,n,1,st[x]-1,w[x]);
}
}
ans=min(ans,f[n]);
}
printf("%d\n",ans);
// fclose(stdin);
// fclose(stdout);
return 0;
}
BZOJ1835,LG2605 [ZJOI2010]基站选址的更多相关文章
- Bzoj1835:[ZJOI2010]基站选址
Sol 设\(f[i][j]\)表示钦定\(i\)建基站,建了\(j\)个基站的最小代价 \(f[i][j]=max(f[l][j-1]+\Sigma_{t=l+1}^{i-1}\)不能影响到的村庄的 ...
- 【LG2605】[ZJOI2010]基站选址
[LG2605][ZJOI2010]基站选址 题面 洛谷 题解 先考虑一下暴力怎么写,设\(f_{i,j}\)表示当前\(dp\)到\(i\),且强制选\(i\),目前共放置\(j\)个的方案数. 那 ...
- 【题解】Luogu P2605 [ZJOI2010]基站选址
原题传送门:P2604 [ZJOI2010]基站选址 看一眼题目,变知道这题一定是dp 设f[i][j]表示在第i个村庄修建第j个基站且不考虑i+1~n个村庄的最小费用 可以得出f[i][j] = M ...
- 题解 [ZJOI2010]基站选址
题解 [ZJOI2010]基站选址 题面 解析 首先考虑一个暴力的DP, 设\(f[i][k]\)表示第\(k\)个基站设在第\(i\)个村庄,且不考虑后面的村庄的最小费用. 那么有\(f[i][k] ...
- luogu P2605 [ZJOI2010]基站选址 线段树优化dp
LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...
- [ZJOI2010]基站选址,线段树优化DP
G. base 基站选址 内存限制:128 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离 ...
- BZOJ1835 [ZJOI2010] 基站选址 【动态规划】【线段树】
题目分析: 首先想一个DP方程,令f[m][n]表示当前在前n个村庄选了m个基站,且第m个基站放在n处的最小值,转移可以枚举上一个放基站的村庄,然后计算两个村庄之间的代价. 仔细思考两个基站之间村庄的 ...
- bzoj1835[ZJOI2010]基站选址
主席树+决策单调,重写一遍比之前短多了……题解:http://www.cnblogs.com/liu-runda/p/6051422.html #include<cstdio> #incl ...
- [ZJOI2010]基站选址
题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄不超过Si的范 ...
随机推荐
- 新概念 Lesson 3 Nice to meet you
Nice to meet you. 你好 打招呼: hi,hello 重点: 打招呼和互相介绍.主系表结构 Is Chang-woo Chinese? 昌武是中国人吗? No,he isn't . H ...
- vue.js 过渡&动画
9-17 在add ,update, remove DOM时 提供多种方式的应用过度效果. 包括以下可选工具:(2大类,css和js) 在css过度和动画中自动应用class 配合使用第三方css动画 ...
- Razor及HtmlHelper学习笔记
Razor 不是编程语言.它是服务器端标记语言. 什么是Razor? Razor 是一种允许您向网页中嵌入基于服务器的代码(Visual Basic 和 C#)的标记语法. 当网页被写入浏览器时,基于 ...
- UVA-818 Cutting Chains (位压缩+暴力搜索)
题目大意:一种环能打开和闭合.现在有n(1<=n<=15)个编号为1~n的环错综复杂的连接着,要打开一些环重新连接使这n个环能构成一条链,问最少需要打开几次环可达到目的? 题目分析:用二进 ...
- Graph (floyd)
Description Everyone knows how to calculate the shortest path in a directed graph. In fact, the oppo ...
- hulu
一. 一开始因为没收到含有共享文档链接的邮件,所以简单自我介绍,聊了几句项目.问了: 1. 玩嗨如果数据库结构变化要怎么办 2. 哈佛项目是否为官方渠道 一直没收到邮件,面试官读网址给我,进到共享文档 ...
- <meta http-equiv="X-UA-Compatible" content="IE=7" />
<meta http-equiv="X-UA-Compatible" content="IE=7" />意思是将IE8用IE7进行渲染,使网页在IE ...
- OC Foundation框架—结构体
一.基本知识 Foundation—基础框架.框架中包含了很多开发中常用的数据类型,如结构体,枚举,类等,是其他ios框架的基础. 如果要想使用foundation框架中的数据类型,那么包含它的主头文 ...
- ora2pg安装及卸载
--ora2pg安装 tar xzf ora2pg-10.x.tar.gz or tar xjf ora2pg-10.x.tar.bz2 cd ora2pg-10.x/ perl Makefile. ...
- learning uboot distro design in am335x-evm board
reference: uboot_dir/doc/README.distro Linux distributions are faced with supporting a variety of bo ...