BZOJ 1835: [ZJOI2010]base 基站选址(DP,线段树)
可以很容易的写出dp方程:
F[i][j]=min(F[l][j-1]+w[l][i])+c[i] (w[i][j]是从l+1到i-1这些点p里,所有满足d[p]+s[p]<d[i] && d[p]-s[p]>d[l]的点的w[p]之和)
考虑i+1,会对方程造成什么变化
w[l][i]会变得跟大了(满足d[p]+s[p]<d[i]的点更多了)
可以发现增长的是一个区间,求和也是一个区间
线段树解决
CODE:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 20100
#define inf 1000000000
struct node {
int l,r,mi,lz;
}t[maxn*8];
#define lc(x) (x<<1)
#define rc(x) ((x<<1)+1)
#define mi(x) t[x].mi
#define lz(x) t[x].lz
#define mid ((l+r)>>1)
#define update(x) mi(x)=min(mi(lc(x)),mi(rc(x)))
int f[maxn],pf[maxn];
int build(int x,int l,int r) {
t[x].l=l,t[x].r=r;
t[x].lz=0;
if (l==r) return t[x].mi=pf[l];
build(lc(x),l,mid);
build(rc(x),mid+1,r);
update(x);
return 0;
}
int pushback(int x) {
if (t[x].l==t[x].r) return 0;
lz(lc(x))+=lz(x),lz(rc(x))+=lz(x);
mi(lc(x))+=lz(x),mi(rc(x))+=lz(x);
lz(x)=0;
}
int query(int x,int x1,int y1){
int l=t[x].l,r=t[x].r;
if (y1<l||x1>r) return inf;
if (x1<=l&&y1<=r) return mi(x);
pushback(x);
return min(query(lc(x),x1,y1),query(rc(x),x1,y1));
}
int add(int x,int x1,int y1,int z) {
int l=t[x].l,r=t[x].r;
if (y1<l||x1>r) return 0;
if (x1<=l&&y1>=r) return lz(x)+=z,mi(x)+=z;
pushback(x);
add(lc(x),x1,y1,z),add(rc(x),x1,y1,z);
update(x);
}
int n,k;
int c[maxn],s[maxn],d[maxn],w[maxn];
int st[maxn],ed[maxn];
vector<int> list[maxn];
int solve(){
int sum=0;
for (int i=1;i<=n;i++) {
f[i]=sum+c[i];
for(int j=0;j<list[i].size();j++) sum+=w[list[i][j]];
}
int ans=f[n];
for (int i=1;i<=k;i++) {
//for (int i=1;i<=n;i++) printf("%d ",f[i]);printf("\n");
memcpy(pf,f,sizeof(pf));
for (int j=1;j<=n;j++) f[j]=inf;
build(1,1,n);
for (int j=1;j<=n;j++){
f[j]=min(f[j],query(1,1,j-1))+c[j];
for (int k=0;k<list[j].size();k++) add(1,1,st[list[j][k]]-1,w[list[j][k]]);
}
ans=min(ans,f[n]);
}
printf("%d\n",ans);
return 0;
}
int main(){
scanf("%d%d",&n,&k);
for (int i=2;i<=n;i++) scanf("%d",d+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);
d[++n]=inf,c[n]=w[n]=s[n]=0;
for (int i=1;i<=n;i++) {
st[i]=lower_bound(d+1,d+1+n,d[i]-s[i])-d;
ed[i]=upper_bound(d+1,d+1+n,d[i]+s[i])-d-1;
list[ed[i]].push_back(i);
}
solve();
return 0;
}
BZOJ 1835: [ZJOI2010]base 基站选址(DP,线段树)的更多相关文章
- BZOJ 1835 [ZJOI2010]base 基站选址:线段树优化dp
传送门 题意 有 $ n $ 个村庄在一排直线上,现在要建造不超过 $ K $ 个通讯基站,基站只能造在村庄处. 第 $ i $ 个村庄距离第 $ 1 $ 个村庄的距离为 $ D_i $ .在此建造基 ...
- BZOJ 1835: [ZJOI2010]base 基站选址 [序列DP 线段树]
1835: [ZJOI2010]base 基站选址 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立 ...
- bzoj 1835 [ZJOI2010]base 基站选址(DP+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1835 [题意] 有n个村庄,每个村庄位于d[i],要求建立不多于k个基站,在第i个村庄 ...
- BZOJ1835: [ZJOI2010]base 基站选址【线段树优化DP】
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- 2018.11.06 bzoj1835: [ZJOI2010]base 基站选址(线段树优化dp)
传送门 二分出每个点不需要付www贡献的范围,然后可以推出转移式子: f[i][j]=f[i−1][k]+value(k+1,j)+c[i]f[i][j]=f[i-1][k]+value(k+1,j) ...
- bzoj 1835: [ZJOI2010]base 基站选址
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- bzoj[1835][ZJOI2010]base 基地选址
bzoj[1835][ZJOI2010]base 基地选址 标签: 线段树 DP 题目链接 题解 这个暴力DP的话应该很容易看出来. dp[i][j]表示造了i个通讯站,并且j是第i个的最小费用. \ ...
- bzoj 1835 base 基站选址 - 动态规划 - 线段树
题目传送门 需要高级权限的传送门 题目大意 有$n$个村庄坐落在一条直线上,第$i \ \ \ (i>1)$个村庄距离第$1$个村庄的距离为$D_i$.需要在这些村庄中建立不超过$K$个通讯基站 ...
- BZOJ 1835 基站选址(DP+线段树)
# include <cstdio> # include <cstring> # include <cstdlib> # include <iostream& ...
随机推荐
- js中的 substring和substr方法
原文: http://www.cnblogs.com/chinafine/archive/2009/02/26/1398771.html 1.substring 方法 定义和用法 substring ...
- poj2528 Mayor's posters(线段树区间覆盖)
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 50888 Accepted: 14737 ...
- C++ 虚基类表指针字节对齐
下面博客转载自别人的,我也是被这个问题坑了快两天了,关于各种虚基类,虚继承,虚函数以及数据成员等引发的一系列内存对齐的问题再次详细描述 先看下面这片代码.在这里我使用了一个空类K,不要被这个东西所迷惑 ...
- Ubuntu Linux下设置IP的配置命令
Ubuntu Linux下设置IP的配置命令 今天装了Ubuntu,但是发现不能上网,开始排查问题: 1.首先确定网络连接是否正确,所用的网线是否可以正常工作 2.查看网卡是否能正常工作,检测的方法如 ...
- selenium Chromediver
Here we use wget to fetch the version number of the latest release, then plug the version into anoth ...
- Spring 之 示例(Java之负基础实战)
接 Spring 之 配置 里面的代码. 现在要进行Controller的开发. 1.引用类 import org.springframework.web.servlet.mvc.Controller ...
- wukong搜索引擎源码解读
转自:https://ayende.com/blog/171745/code-reading-wukong-full-text-search-engine I like reading code, a ...
- HBuilder mui引导页制作
http://www.bcty365.com/content-146-2582-1.html
- OC类方法的调用
有个Person类,有个Phone类,Person类想使用Phone类中打电话和发短信的方法 1.Phone.h Phone有kind和color属性 ,方法定义的时候将用到的参数都 ...
- 滚动视图(ScrollView)的功能与用法
滚动视图ScrollView由FrameLayout派生而出,它就是一个用于为普通组件添加滚动条的组件.ScrollView里最多只能包含一个组件,而ScrollVew的作用就是为该组件添加垂直滚动条 ...