bzoj[1835][ZJOI2010]base 基地选址

标签: 线段树 DP


题目链接

题解

这个暴力DP的话应该很容易看出来。
dp[i][j]表示造了i个通讯站,并且j是第i个的最小费用。
\[ dp[i][j]=min\{dp[i-1][k]+cost(k,j)\}+c[j] \]
这个是\(O(n^2k)\)的,很明显我们要对其进行优化。
首先i这一维可以滚掉。

而其实麻烦之处就是cost(i,j)这里,我们肯定不能对其进行预处理。只能够利用其本身的一些性质来做。
我们发现,每个人不需要补偿时是在一段区间内的。可以直接先二分这段区间预处理出来。
然后把这些区间按照右端点排序,每扫到右端点就把左端点之前的加上这个区间的值(补偿值)。
具体实现,由于右端点的值域是\([1,n]\),我们可以沿用一下存邻接表的那套理论。
区间加值的话,用线段树维护一下就好。

感觉线段树实现过程讲的不太清,总结一下算法步骤:
1.每次线段树设为上一次dp的结果(因为要用这个更新啊)。
2.dp[j]直接是线段树中询问[1,j-1] + c[j]。
3.维护补偿的值,在把右端点为j的在线段树中更新[1,左端点-1]。

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
inline int read()
{int sum=0,p=1;char ch=getchar();while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();if(ch=='-')p=-1,ch=getchar();while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();return sum*p;
}const int maxn=20020;int n,k,w[maxn],d[maxn],cost[maxn],s[maxn];
int st[maxn],ed[maxn];
vector <int>g[maxn];
const int inf=0x3f3f3f3f;
void init()
{n=read();k=read();REP(i,2,n)d[i]=read();REP(i,1,n)cost[i]=read();REP(i,1,n)s[i]=read();REP(i,1,n)w[i]=read();n++;k++;w[n]=d[n]=inf;s[n]=cost[n]=0;REP(i,1,n){st[i]=lower_bound(d+1,d+n+1,d[i]-s[i])-d;ed[i]=lower_bound(d+1,d+n+1,d[i]+s[i])-d;if(d[ed[i]]>d[i]+s[i])ed[i]--;g[ed[i]].push_back(i);}
}struct node {int mn,lz;void Merge(node a,node b){mn=min(a.mn,b.mn);}
};
node c[maxn*4];
int dp[maxn];#define lc (o<<1)
#define rc (o<<1 | 1)
#define left lc,l,mid
#define right rc,mid+1,rvoid make_tree(int o,int l,int r)
{c[o].lz=0;if(l==r){c[o].mn=dp[l];return;}int mid=(l+r)>>1;make_tree(left);make_tree(right);c[o].Merge(c[lc],c[rc]);
}inline void push_down(int o,int l,int r)
{if(c[o].lz){c[lc].lz+=c[o].lz;c[rc].lz+=c[o].lz;c[lc].mn+=c[o].lz;c[rc].mn+=c[o].lz;c[o].lz=0;}
}void update(int ql,int qr,int x,int o,int l,int r)
{if(ql>qr)return;if(ql<=l && r<=qr){c[o].mn+=x;c[o].lz+=x;return;}push_down(o,l,r);int mid=(l+r)>>1;if(ql<=mid)update(ql,qr,x,left);if(qr>mid)update(ql,qr,x,right);c[o].Merge(c[lc],c[rc]);
}int query(int ql,int qr,int o,int l,int r)
{if(ql>qr)return 0;if(ql<=l && r<=qr){return c[o].mn;}push_down(o,l,r);int mid=(l+r)>>1,ans=inf;if(ql<=mid)ans=min(ans,query(ql,qr,left));if(qr>mid)ans=min(ans,query(ql,qr,right));return ans;
}int ans=inf;void doing()
{int sum=0;REP(j,1,n){dp[j]=sum+cost[j];REP(l,0,g[j].size()-1){int x=g[j][l];sum+=w[x];}}ans=min(ans,dp[n]);REP(i,2,k){make_tree(1,1,n);//REP(j,1,i)dp[j]=dp[j-1]+cost[j];REP(j,1,n){dp[j]=query(1,j-1,1,1,n)+cost[j];//update(j,j,dp[j],1,1,n);REP(l,0,g[j].size()-1){int x=g[j][l];update(1,st[x]-1,w[x],1,1,n);}}ans=min(ans,dp[n]);}printf("%d\n",ans);
}int main()
{freopen("base.in","r",stdin);freopen("base.out","w",stdout);init();doing();return 0;
}

转载于:https://www.cnblogs.com/gzy-cjoier/p/7638888.html

bzoj[1835][ZJOI2010]base 基地选址相关推荐

  1. BZOJ1835: [ZJOI2010]base 基站选址(线段树优化Dp)

    Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...

  2. 央视筹备国家网络电视台 研发基地选址成都

    2月18日傍晚,一则坊间迅速流传的消息,在业内引起轩然大波. 这则来自国家广电总局网站的消息称,央视网(CCTV.com)正按照指示筹备建设国家网络电视台,日前经与市场调查研究公司合作进行调研. 当晚 ...

  3. [BZOJ 1834] [ZJOI2010]network 网络扩容

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 SecMemory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一个扩 ...

  4. bzoj 1833: [ZJOI2010]count 数字计数(数字0-9的个数)

    1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec  Memory Limit: 64 MB Submit: 3528  Solved: 1553 [Submit ...

  5. BZOJ 1833 ZJOI2010 count 数字计数 数位DP

    题目大意:求[a,b]间全部的整数中0~9每一个数字出现了几次 令f[i]为i位数(算前导零)中每一个数出现的次数(一定是同样的,所以仅仅记录一个即可了) 有f[i]=f[i-1]*10+10^(i- ...

  6. BZOJ 2111 [ZJOI2010]Perm 排列计数:Tree dp + Lucas定理

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2111 题意: 给定n,p,问你有多少个1到n的排列P,对于任意整数i∈[2,n]满足P[i ...

  7. bzoj 1834: [ZJOI2010]network 网络扩容【最大流+最小费用最大流】

    第一问直接跑最大流即可.建图的时候按照费用流建,费用为0. 对于第二问,在第一问dinic剩下的残量网络上建图,对原图的每条边(i,j),建(i,j,inf,cij),表示可以用c的花费增广这条路.然 ...

  8. [BZOJ 2111][ZJOI2010]Perm 排列计数(Lucas定理)

    Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic ...

  9. BZOJ 1833: [ZJOI2010]count 数字计数

    1833 思路:数位dp 代码: #include<bits/stdc++.h> using namespace std; #define fi first #define se seco ...

最新文章

  1. Asp.net控件开发学习笔记(三)-控件开发基础
  2. 一劳永逸-解决人类未来长期-暴露在病毒的方案-致所有中国的科技公司一封信
  3. 青龙面板跑滴滴果园,5天种水果。
  4. 34 linux监控平台
  5. python库整理:os
  6. 游戏开发者需要注意的4个内存使用问题
  7. 浅谈深浅拷贝问题(这里只针对拷贝构造函数和赋值运算符重载)和简易srting类模拟实现
  8. makefile中的patsubst, wildcard, notdir
  9. java处理url中的特殊字符%等
  10. 将结构体写入文件_将COCO检测结果写入json文件
  11. POST 方式上传图片
  12. Scale-up and Scale-out
  13. 计算机仿真的特点,计算机仿真的基本特点与基本流程.doc
  14. Skyline软件二次开发初级——8如何在WEB页面中的三维地图上管理信息树
  15. 基于 VIVADO 的 AM 调制解调(2)工程实现
  16. 新浪短网址api接口——5个可生成新浪t.cn短链的在线工具网站评测
  17. Dev-C++ 中t添加EasyX绘图库
  18. 《后来》可爱MM演唱 视频
  19. 飞猪登录器推荐《怪物猎人世界》萌新入坑武器装备推荐
  20. GROUP Function

热门文章

  1. smarty模板截取字符串乱码问题完美解决```````
  2. php 打开任意文件下载,TEC-004-php文件下载任意文件读取漏洞修复
  3. java params 参数_将params作为参数传递给类扩展方法的函数
  4. 通讯录_怎么恢复手机通讯录?最完整手机通讯录恢复方法大公开
  5. as本地仓库更改_Android Studio 之 Gradle与Project Structure详解
  6. oracle照片字节大小值,Oracle每条记录的平均字节数
  7. go操作网页元素_UI自动化21heliumS元素定位方式
  8. linux docker安装mysql_Linux-docker安装mysql
  9. pbp 读取 mysql数据_SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)...
  10. 00截断上传绕过_【文件上传与解析】文件上传与解析漏洞总结v1.0