BZOJ1835: [ZJOI2010]base 基站选址(线段树优化Dp)
Description
有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di。需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci。如果在距离第i个村庄不超过Si的范围内建立了一个通讯基站,那么就成它被覆盖了。如果第i个村庄没有被覆盖,则需要向他们补偿,费用为Wi。现在的问题是,选择基站的位置,使得总费用最小。 输入数据 (base.in) 输入文件的第一行包含两个整数N,K,含义如上所述。 第二行包含N-1个整数,分别表示D2,D3,…,DN ,这N-1个数是递增的。 第三行包含N个整数,表示C1,C2,…CN。 第四行包含N个整数,表示S1,S2,…,SN。 第五行包含N个整数,表示W1,W2,…,WN。
Input
输出文件中仅包含一个整数,表示最小的总费用。
Output
3 2 1 2 2 3 2 1 1 0 10 20 30
Sample Input
Sample Output
100%的数据中,K<=N,K<=100,N<=20,000,Di<=1000000000,Ci<=10000,Si<=1000000000,Wi<=10000。
解题思路:
一道好题,不过我没时间写题解了,暂且咕在这里。
代码:
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
typedef long long lnt;
const int N=;
struct trnt{
lnt lzt;
lnt minv;
}tr[N<<],stt;
int n,k;
lnt w[N],s[N],d[N],c[N];
int lp[N],rp[N];
lnt dp[N];
std::vector<lnt>lim[N];
void pushup(int spc)
{
tr[spc].minv=std::min(tr[lll].minv,tr[rrr].minv);
return ;
}
void add(int spc,lnt v)
{
tr[spc].minv+=v;
tr[spc].lzt+=v;
return ;
}
void pushdown(int spc)
{
if(tr[spc].lzt)
{
add(lll,tr[spc].lzt);
add(rrr,tr[spc].lzt);
tr[spc].lzt=;
}
return ;
}
void build(int l,int r,int spc)
{
tr[spc]=stt;
if(l==r)
{
tr[spc].minv=dp[l];
return ;
}
int mid=(l+r)>>;
build(l,mid,lll);
build(mid+,r,rrr);
pushup(spc);
return ;
}
void update(int l,int r,int ll,int rr,int spc,lnt v)
{
if(l>rr||ll>r)
return ;
if(ll<=l&&r<=rr)
{
add(spc,v);
return ;
}
int mid=(l+r)>>;
pushdown(spc);
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
lnt query(int l,int r,int ll,int rr,int spc)
{
if(l>rr||ll>r)
return 0x3f3f3f3f;
if(ll<=l&&r<=rr)
return tr[spc].minv;
int mid=(l+r)>>;
pushdown(spc);
return std::min(query(l,mid,ll,rr,lll),query(mid+,r,ll,rr,rrr));
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
scanf("%lld",&d[i]);
for(int i=;i<=n;i++)
scanf("%lld",&c[i]);
for(int i=;i<=n;i++)
scanf("%lld",&s[i]);
for(int i=;i<=n;i++)
scanf("%lld",&w[i]);
for(int i=;i<=n;i++)
{
lp[i]=rp[i]=i;
int l=,r=i-;
while(l<=r)
{
int mid=(l+r)>>;
if(d[i]-d[mid]<=s[i])
{
r=mid-;
lp[i]=mid;
}else
l=mid+;
}
l=i+,r=n;
while(l<=r)
{
int mid=(l+r)>>;
if(d[mid]-d[i]<=s[i])
{
l=mid+;
rp[i]=mid;
}else
r=mid-;
}
lim[rp[i]].push_back(i);
}
lnt sum=;
for(int i=;i<=n;i++)
{
dp[i]=c[i]+sum;
for(int j=;j<lim[i].size();j++)
sum+=w[lim[i][j]];
}
lnt ans=sum;
for(int i=;i<=k;i++)
{
build(,n,);
for(int j=;j<=n;j++)
{
dp[j]=query(,n,,j-,)+c[j];
for(int o=;o<lim[j].size();o++)
update(,n,,lp[lim[j][o]]-,,w[lim[j][o]]);
}
ans=std::min(ans,query(,n,,n,));
}
printf("%lld\n",ans);
return ;
}
BZOJ1835: [ZJOI2010]base 基站选址(线段树优化Dp)的更多相关文章
- 【BZOJ1835】[ZJOI2010]base 基站选址 线段树+DP
[BZOJ1835][ZJOI2010]base 基站选址 Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯 ...
- 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$
正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ...
- [ZJOI2010]基站选址,线段树优化DP
G. base 基站选址 内存限制:128 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离 ...
- luogu P2605 [ZJOI2010]基站选址 线段树优化dp
LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...
- BZOJ 1835 [ZJOI2010]基站选址 (线段树优化DP)
题目大意:略 洛谷题面传送门 BZOJ题面传送门 注意题目的描述,是村庄在一个范围内去覆盖基站,而不是基站覆盖村庄,别理解错了 定义$f[i][k]$表示只考虑前i个村庄,一共建了$k$个基站,最后一 ...
- luogu2605 基站选址 (线段树优化dp)
设f[i][j]表示在第i个村庄建第j个基站的花费 那么有$f[i][j]=min\{f[k][j-1]+w[k,i]\}$,其中w[k,i]表示在k,i建基站,k,i中间的不能被满足的村庄的赔偿金之 ...
- bzoj1835[ZJOI2010]base基站选址
据说正解是什么线段树优化DP,但是作为脑子有坑选手,我们需要5k的做法: 主席树+决策单调性..... F[m][i]表示已经放置了m个基站,第m个基站放置在第i个村庄,第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) ...
- bzoj1835: [ZJOI2010]base 基站选址
新的一年新的开始.结果第一题就用了几乎一周.而且感觉很不好. 先检讨自己.最近写的各种数据结构模板基本没打过出来,各种细节崩盘,这题线段树都居然被lazy标记没清零卡挂. DP还是博大精深,这东西感觉 ...
随机推荐
- Python的matplotlib库画图不能显示中文问题解决
有两种解决办法: 一种是在代码里设置为能显示中文的字体,如微软雅黑(msyh.ttf)和黑体(simsun.ttc) 如下在要画图的代码前添加: import matplotlib.pyplot as ...
- oracle创建静态监听
[oracle@localhost admin]$ pwd /u01/app/oracle/product/11.2.0/dbhome_1/network/admin [oracle@localhos ...
- unity C# StackOverflowException
有时候图省事,属性这样写public int pageCount{get{return pageCount;}set{pageCount=value;}}可能会报栈溢出的错误, StackOverfl ...
- springMVC的rest风格的url请求
rest是一个架构风格,用url来访问网络上的任何资源.rest的一种思想就是用http中的动作get,post,put,delete,来进行增删改查. 这里介绍的是springMVC的rest请求. ...
- Gonet2 游戏server框架解析之gRPC提高(5)
上一篇blog是关于gRPC框架的基本使用,假设说gRPC仅仅是远程发几个參数,那和一个普通的http请求也没多大区别了. 所以今天我就来学习一下gRPC高级一点的用法. 流! 流能够依据用法,分为单 ...
- iOS Code Sign error: Provisioning profile can't be found 解决方式
出现error的过程:在执行另外一个xcode项目重置了code sign.回到原来的项目的时候出现这个error 修复方法: targe-build settings-code signing id ...
- JAVA并发-内置锁和ThreadLocal
上一篇博客讲过,当多个线程访问共享的可变变量的时候,可以使用锁来进行线程同步.那么如果线程安全性存在的3个前提条件不同时存在的话,自然就不需要考虑线程安全性了.或者说如果我们能够将某个共享变量变为局部 ...
- 1.MVC概要与angular概要、模板与数据绑定
转自:https://www.cnblogs.com/best/p/6242011.html#_label3_0_8_2 一.前端MVC概要 1.1.库与框架的区别 1.2.AMD与CMD 1.2.前 ...
- BZOJ 1503 treap
思路: treap (算是基本操作吧-..) 加减的操作数很少 就暴力好啦 每回判断一下最小的数是不是比M小 如果是 就删,继续判断 搞定. //By SiriusRen #include <c ...
- P2617 Dynamic Ranking
题目描述 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤ ...