[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。
输出格式:
输出文件中仅包含一个整数,表示最小的总费用。
输入输出样例
说明
40%的数据中,N<=500;
100%的数据中,K<=N,K<=100,N<=20,000,Di<=1000000000,Ci<=10000,Si<=1000000000,Wi<=10000。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
struct Node
{
int next,to;
} edge[];
int head[],num;
lol Min[],f[];
lol lazy[];
int n,k,d[],c[],l[],w[];
int st[],ed[],inf=1e15;
lol ans,now;
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void build(int rt,int l,int r)
{
lazy[rt]=;
if (l==r)
{
Min[rt]=f[l];
return;
}
int mid=(l+r)/;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
Min[rt]=min(Min[rt<<],Min[rt<<|]);
}
void pushdown(int rt)
{
if (lazy[rt])
{
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
Min[rt<<]+=lazy[rt];
Min[rt<<|]+=lazy[rt];
lazy[rt]=;
}
}
void update(int rt,int l,int r,int L,int R,lol d)
{
if (l>=L&&r<=R)
{
Min[rt]+=d;
lazy[rt]+=d;
return;
}
int mid=(l+r)/;
pushdown(rt);
if (L<=mid) update(rt<<,l,mid,L,R,d);
if (R>mid) update(rt<<|,mid+,r,L,R,d);
Min[rt]=min(Min[rt<<],Min[rt<<|]);
}
lol query(int rt,int l,int r,int L,int R)
{
if (l>=L&&r<=R)
{
return Min[rt];
}
int mid=(l+r)/;
lol s=2e15;
pushdown(rt);
if (L<=mid) s=min(s,query(rt<<,l,mid,L,R));
if (R>mid) s=min(s,query(rt<<|,mid+,r,L,R));
Min[rt]=min(Min[rt<<],Min[rt<<|]);
return s;
}
int main()
{
int i,j,p;
cin>>n>>k;
for (i=; i<=n; i++)
scanf("%d",&d[i]);
for (i=; i<=n; i++)
scanf("%d",&c[i]);
for (i=; i<=n; i++)
scanf("%d",&l[i]);
for (i=; i<=n; i++)
scanf("%d",&w[i]);
++n;
++k;
w[n]=inf;
d[n]=inf;
for (i=; i<=n; i++)
{
st[i]=lower_bound(d+,d+n+,d[i]-l[i])-d;
ed[i]=lower_bound(d+,d+n+,d[i]+l[i])-d;
if (d[ed[i]]>d[i]+l[i]) ed[i]--;
add(ed[i],i);
}
ans=2e15;
for (i=; i<=n; i++)
{
f[i]=now+c[i];
for (j=head[i]; j; j=edge[j].next)
{
int v=edge[j].to;
now+=w[v];
}
}
ans=min(ans,f[n]);
for (i=; i<=k; i++)
{
build(,,n);
for (j=; j<=n; j++)
{
if (j>)
f[j]=query(,,n,,j-)+c[j];
else f[j]=c[j];
for (p=head[j]; p; p=edge[p].next)
{
int v=edge[p].to;
if (st[v]>) update(,,n,,st[v]-,w[v]);
}
}
ans=min(ans,f[n]);
}
cout<<ans;
}
[ZJOI2010]基站选址的更多相关文章
- 【题解】Luogu P2605 [ZJOI2010]基站选址
原题传送门:P2604 [ZJOI2010]基站选址 看一眼题目,变知道这题一定是dp 设f[i][j]表示在第i个村庄修建第j个基站且不考虑i+1~n个村庄的最小费用 可以得出f[i][j] = M ...
- 【LG2605】[ZJOI2010]基站选址
[LG2605][ZJOI2010]基站选址 题面 洛谷 题解 先考虑一下暴力怎么写,设\(f_{i,j}\)表示当前\(dp\)到\(i\),且强制选\(i\),目前共放置\(j\)个的方案数. 那 ...
- 题解 [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)个村庄距离 ...
- bzoj 1835: [ZJOI2010]基站选址
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- BZOJ1835 [ZJOI2010] 基站选址 【动态规划】【线段树】
题目分析: 首先想一个DP方程,令f[m][n]表示当前在前n个村庄选了m个基站,且第m个基站放在n处的最小值,转移可以枚举上一个放基站的村庄,然后计算两个村庄之间的代价. 仔细思考两个基站之间村庄的 ...
- BZOJ1835,LG2605 [ZJOI2010]基站选址
题意 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为\(D_i\) 需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为\(C_i\) 如果在距离第i个村 ...
- P2605 [ZJOI2010]基站选址
题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄不超过Si的范 ...
随机推荐
- 一台windows主机上运行2个tomcat
为了运行2个不同的项目,需要在一台机上运行2个tomcat,但是发现运行第二个tomcat时,总会加载第一个tomcat中的项目,也就是实际运行的是第一个tomcat 所以需要做如下配置: 1.修改第 ...
- 如何减小ios安装包大小
以前的老文章了,搬到cnblog 更小的安装包意味着更快的下载安装速度,也往往意味着更快的加载运行速度,是优化ios应用的一个重要方面,本文主要参考<减小iOS应用程序的大小>,在实际测试 ...
- 静态关键字static用法。
static的特点:1,static是一个修饰符,用于修饰成员.2,static修饰的成员被所有的对象所共享.3,static优先于对象存在,因为static的成员随着类的加载就已经存在了. 4,st ...
- ES6常用新特性
https://segmentfault.com/a/1190000011976770?share_user=1030000010776722 该文章为转载文章!仅个人喜好收藏文章! 1.前言 前几天 ...
- Linux的rsync 配置,用于服务器之间远程传大量的数据
[教程主题]:rsync [课程录制]: 创E [主要内容] [1] rsync介绍 Rsync(Remote Synchronize) 是一个远程资料同步工具,可通过LAN/WAN快速同步多台主机, ...
- Python机器学习—导入各种数据的N种办法
pandas 读取数据 一.导入一般的文件 1.read_csv(),用来读取CSV文件 官方文档是这么说的:Read CSV (comma-separated) file into DataFram ...
- Linux背景知识(1)RedHat和Centos
Redhat有收费的商业版和免费的开源版,商业版的业内称之为RHEL(Red Hat Enterprise Linux)系列, 而这个CentOS(Community ENTerprise Opera ...
- python入门(2)python的安装
python入门(2)python的安装 Python是跨平台的,可以运行在Windows.Mac和各种Linux/Unix系统上. 2.x还是3.x Python有两个版本,一个是2.x版,一个是3 ...
- Python3安装Requests
安装Requests费了1天的时间,囧.终于还是在官网找到解决方法,可以参考这个http://docs.python-requests.org/en/latest/user/install/#inst ...
- Window7系统下安装jdk
根据电脑的操作系统下载相对于的jdk版本(32位或64位),我安装的是:java_jdk1.7 [计算机]——[属性]——[高级系统设置]——高级——[环境变量] 系统变量——>新建JAVA_H ...