题解 P2605 【[ZJOI2010]基站选址】(From luoguBlog)
线段树优化dp
数组f[i][j]表示在前i个村庄内,第j个基站建在i处的最小费用
根据交线牛逼法和王鹤松式可得方程
f[i][j]=min(f[k][j−1]+cost(k,i))
cost(k,i)表示第i~k个村庄之间没有被基站覆盖的村庄所需的赔偿费用,计算费用的复杂度为O(n)
利用二分查找预处理每个位置的需求范围bef[i],beh[i]
之后就是利用线段树维护f[]+cost()的最小值,区间查询区间更新
当beh[x]=i,若i不建造,则加cost(可能存在很多x,前向星或vector存储)
Code:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#define ls(k) k<<1
#define rs(k) k<<1|1
using namespace std;
const int N=20010,K=110;
int dis[N],s[N],w[N],c[N],f[N];
int n,m,bef[N],beh[N];
int tot=0,to[N<<1],head[N<<1],nxt[N<<1];
int mn[N<<2],lz[N<<2];
void Add(int x,int y)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void up(int k)
{
	mn[k]=min(mn[ls(k)],mn[rs(k)]);
}
void build(int k,int l,int r)
{
	lz[k]=0;
	if(l==r)
	{
		mn[k]=f[l];
		return ;
	}
	int mid=l+r>>1;
	build(ls(k),l,mid);
	build(rs(k),mid+1,r);
	up(k);
}
void down(int k)
{
	lz[ls(k)]+=lz[k];
	lz[rs(k)]+=lz[k];
	mn[ls(k)]+=lz[k];
	mn[rs(k)]+=lz[k];
	lz[k]=0;
}
int query(int k,int l,int r,int L,int R)
{
	if(L>R)return 0x3f3f3f3f;
	if(L<=l&&R>=r)return mn[k];
	int mid=l+r>>1;
	if(lz[k])down(k);
	int res=0x3f3f3f3f;
	if(L<=mid)res=min(res,query(ls(k),l,mid,L,R));
	if(mid<R)res=min(res,query(rs(k),mid+1,r,L,R));
	return res;
}
void change(int k,int l,int r,int L,int R,int vl)
{
	if(L>R)return ;
	if(L<=l&&R>=r)
	{
		lz[k]+=vl;
		mn[k]+=vl;
		return ;
	}
	if(lz[k])down(k);
	int mid=l+r>>1;
	if(L<=mid)change(ls(k),l,mid,L,R,vl);
	if(R>mid)change(rs(k),mid+1,r,L,R,vl);
	up(k);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;i++)scanf("%d",&dis[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]);
	n++,m++;
	dis[n]=w[n]=0x3f3f3f3f;
	for(int i=1;i<=n;i++)
	{
		bef[i]=lower_bound(dis+1,dis+n+1,dis[i]-s[i])-dis;
		beh[i]=lower_bound(dis+1,dis+n+1,dis[i]+s[i])-dis;
		if(dis[beh[i]]>dis[i]+s[i])beh[i]--;
		Add(beh[i],i);
	}
	int now=0;
	for(int j=1;j<=n;j++)
	{
		f[j]=now+c[j];
		for(int i=head[j];i;i=nxt[i])now+=w[to[i]];
	}
	int ans=f[n];
	for(int i=2;i<=m;i++)
	{
		build(1,1,n);
		for(int j=1;j<=n;j++)
		{
			f[j]=query(1,1,n,1,j-1)+c[j];
			for(int p=head[j];p;p=nxt[p])
				change(1,1,n,1,bef[to[p]]-1,w[to[p]]);
		}
		ans=min(ans,f[n]);
	}
	cout<<ans<<endl;
	return 0;
}
题解 P2605 【[ZJOI2010]基站选址】(From luoguBlog)的更多相关文章
- 【题解】Luogu P2605 [ZJOI2010]基站选址
		原题传送门:P2604 [ZJOI2010]基站选址 看一眼题目,变知道这题一定是dp 设f[i][j]表示在第i个村庄修建第j个基站且不考虑i+1~n个村庄的最小费用 可以得出f[i][j] = M ... 
- luogu P2605 [ZJOI2010]基站选址 线段树优化dp
		LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ... 
- P2605 [ZJOI2010]基站选址
		题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄不超过Si的范 ... 
- luogu P2605 [ZJOI2010]基站选址
		luogu 先考虑朴素dp,设\(f_{i,j}\)表示在第\(i\)个村庄放了基站,一共放了\(j\)次,且只考虑前面村庄影响的答案.这里可以把\(j\)放在外面枚举,然后从\(f_{k,j-1}( ... 
- 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$
		正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ... 
- 题解 [ZJOI2010]基站选址
		题解 [ZJOI2010]基站选址 题面 解析 首先考虑一个暴力的DP, 设\(f[i][k]\)表示第\(k\)个基站设在第\(i\)个村庄,且不考虑后面的村庄的最小费用. 那么有\(f[i][k] ... 
- 【LG2605】[ZJOI2010]基站选址
		[LG2605][ZJOI2010]基站选址 题面 洛谷 题解 先考虑一下暴力怎么写,设\(f_{i,j}\)表示当前\(dp\)到\(i\),且强制选\(i\),目前共放置\(j\)个的方案数. 那 ... 
- [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个村庄 ... 
随机推荐
- pam_cracklib.so模块
			pam_cracklib.so中有很多参数可以选择,具体配置如下: debug此选为记录Syslog日志. type=safe输入新密码的时候给予的提示. retry=N改变输入密码的次数,默认值是1 ... 
- V - 吉哥系列故事――完美队形I Manacher
			吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要 ... 
- python 执行环境
			一些函数 执行其它非python程序 1 一些函数 callable callable()是一个布尔函数,确定一个对象是否可以通过函数操作符(())来调用.如果函数可调用便返回True,否则便是Fal ... 
- Python开发工具安装
			v阅读目录 v写在前面 v基本概念 vWindows搭建python开发环境 v从Hello World开始 v博客总结 v博客前言 从大学开始玩python到现在参加工作,已经有5年了,现在的公司是 ... 
- 多个机器获取微信access-token导致的有效性问题
			多个机器获取微信access-token导致的有效性问题 单个机器获取的access-token,只有最后一个是有效的: 多个机器各自获取自己的access-token,都是各自有效的: 在服务器和本 ... 
- IE新发现
			近期用thinkphp写的小程序在IE上測试的时候偶然发现原来IE不兼容的不止是样式啊!!! 震惊哭了~ 在火狐上面嗖嗖的一点bug也没有,在IE上面跟死水一样.. .. 那么问题来了:我的问题是出如 ... 
- java的死锁学习
			学习java的死锁写的代码 也是看书上的然后自己敲了一个 <span style="font-size:18px;">package synchronization.j ... 
- ExtJs 下拉单联动,次级下拉框查询模式
			queryMode : 'local' 如果下拉框的值是本地数据,最好设定queryMode为local,这样可以提高用户的响应速度 
- DBI(i80)/DPI(RGB)/DSI【转】
			本文转载自:http://blog.csdn.net/liuxd3000/article/details/17437317 (1)DBI接口 A,也就是通常所讲的MCU借口,俗称80 system接口 ... 
- poi读取word2003(.doc文档)中的表格
			poi读取word2003(.doc文档)中的表格 Jakarta POI 是apache的子项目,目标是处理ole2对象.它提供了一组操纵Windows文档的Java API.在网上见到好多通过po ... 
