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& ...
随机推荐
- IOS开发-UI学习-NSMutableAttributedString(带属性的字符串)的使用
带属性的字符串: NSString *aa = @"hellochinaIloveYou!"; NSMutableAttributedString *mas = [[NSMutab ...
- IOS开发-OC学习-kvc,kvo
kvc是用来方便的设置实例的属性值的,比如person类的实例p1有一个name的属性,那么我们可以通过kvc去设置p1的name,语法是: [ 对象 setValue:@"xiaming& ...
- IOS 代理的简单实现
原文 http://www.cnblogs.com/lovekarri/archive/2012/03/04/2379197.html 昨天做了一个demo,用到了简单代理. delegate是ios ...
- Angular - - ngClass、ngClassEven、ngClassOdd、ngStyle
这几个都关于样式及类名修改的,所以先把样式代码贴上吧. .red{color:red} .blue{color:blue} 写案例用到的样式就这么简单的两个,下面进入正题. ngClass ngCla ...
- Mysql中常用的函数汇总
Mysql中常用的函数汇总: 一.数学函数abs(x) 返回x的绝对值bin(x) 返回x的二进制(oct返回八进制,hex返回十六进制)ceiling(x) 返回大于x的最小整数值exp(x) 返回 ...
- 国民身份证号码校验之“C#/Winform方法实现+案例分析”
根据[中华人民共和国国家标准 GB 11643-1999]中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出 ...
- centos 用户管理
3.使用命令管理账户 useradd 选项 用户名//添加新用户 usermod 选项 用户名//修改已经存在的用户 userdel -r 用户名//删除用户表示自家目录一起删除. grou ...
- 几种常用的控件(下拉框 可选框 起止日期 在HTML页面直接读取当前时间)
下拉框 <div class="form-group"> <label class="col-xs-3 c ...
- 仿网易邮箱5.0(四):信息提示插件(tips.js)
信息提示插件,在平常的开发中也是经常乃至的一个插件,像是一些辅助信息的提示,如:加载成功.提交信息成功或失败等等.这个插件在163邮箱中用在切换标签时提示加载状态. 下面我们先来分析一下这个小插件需要 ...
- easyui弹出窗关闭前调用确认窗口,先关闭页面后调用弹出窗口
弹出窗关闭的时候提示是否关闭,同时进行一些对应的方法调用, 然而在进行页面关闭调用的时候,往往页面关闭了,才弹出确认对话框, $.messager.confirm和panel的onBeforeClos ...