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。
解题思路:
一道好题,不过我没时间写题解了,暂且咕在这里。
代码:
1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<algorithm> 5 #define lll spc<<1 6 #define rrr spc<<1|1 7 typedef long long lnt; 8 const int N=30010; 9 struct trnt{ 10 lnt lzt; 11 lnt minv; 12 }tr[N<<2],stt; 13 int n,k; 14 lnt w[N],s[N],d[N],c[N]; 15 int lp[N],rp[N]; 16 lnt dp[N]; 17 std::vector<lnt>lim[N]; 18 void pushup(int spc) 19 { 20 tr[spc].minv=std::min(tr[lll].minv,tr[rrr].minv); 21 return ; 22 } 23 void add(int spc,lnt v) 24 { 25 tr[spc].minv+=v; 26 tr[spc].lzt+=v; 27 return ; 28 } 29 void pushdown(int spc) 30 { 31 if(tr[spc].lzt) 32 { 33 add(lll,tr[spc].lzt); 34 add(rrr,tr[spc].lzt); 35 tr[spc].lzt=0; 36 } 37 return ; 38 } 39 void build(int l,int r,int spc) 40 { 41 tr[spc]=stt; 42 if(l==r) 43 { 44 tr[spc].minv=dp[l]; 45 return ; 46 } 47 int mid=(l+r)>>1; 48 build(l,mid,lll); 49 build(mid+1,r,rrr); 50 pushup(spc); 51 return ; 52 } 53 void update(int l,int r,int ll,int rr,int spc,lnt v) 54 { 55 if(l>rr||ll>r) 56 return ; 57 if(ll<=l&&r<=rr) 58 { 59 add(spc,v); 60 return ; 61 } 62 int mid=(l+r)>>1; 63 pushdown(spc); 64 update(l,mid,ll,rr,lll,v); 65 update(mid+1,r,ll,rr,rrr,v); 66 pushup(spc); 67 return ; 68 } 69 lnt query(int l,int r,int ll,int rr,int spc) 70 { 71 if(l>rr||ll>r) 72 return 0x3f3f3f3f; 73 if(ll<=l&&r<=rr) 74 return tr[spc].minv; 75 int mid=(l+r)>>1; 76 pushdown(spc); 77 return std::min(query(l,mid,ll,rr,lll),query(mid+1,r,ll,rr,rrr)); 78 } 79 int main() 80 { 81 scanf("%d%d",&n,&k); 82 for(int i=2;i<=n;i++) 83 scanf("%lld",&d[i]); 84 for(int i=1;i<=n;i++) 85 scanf("%lld",&c[i]); 86 for(int i=1;i<=n;i++) 87 scanf("%lld",&s[i]); 88 for(int i=1;i<=n;i++) 89 scanf("%lld",&w[i]); 90 for(int i=1;i<=n;i++) 91 { 92 lp[i]=rp[i]=i; 93 int l=1,r=i-1; 94 while(l<=r) 95 { 96 int mid=(l+r)>>1; 97 if(d[i]-d[mid]<=s[i]) 98 { 99 r=mid-1; 100 lp[i]=mid; 101 }else 102 l=mid+1; 103 } 104 l=i+1,r=n; 105 while(l<=r) 106 { 107 int mid=(l+r)>>1; 108 if(d[mid]-d[i]<=s[i]) 109 { 110 l=mid+1; 111 rp[i]=mid; 112 }else 113 r=mid-1; 114 } 115 lim[rp[i]].push_back(i); 116 } 117 lnt sum=0; 118 for(int i=1;i<=n;i++) 119 { 120 dp[i]=c[i]+sum; 121 for(int j=0;j<lim[i].size();j++) 122 sum+=w[lim[i][j]]; 123 } 124 lnt ans=sum; 125 for(int i=1;i<=k;i++) 126 { 127 build(1,n,1); 128 for(int j=1;j<=n;j++) 129 { 130 dp[j]=query(1,n,1,j-1,1)+c[j]; 131 for(int o=0;o<lim[j].size();o++) 132 update(1,n,1,lp[lim[j][o]]-1,1,w[lim[j][o]]); 133 } 134 ans=std::min(ans,query(1,n,1,n,1)); 135 } 136 printf("%lld\n",ans); 137 return 0; 138 }
转载于:https://www.cnblogs.com/blog-Dr-J/p/10205800.html
BZOJ1835: [ZJOI2010]base 基站选址(线段树优化Dp)相关推荐
- 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛H题小Y与多米诺骨牌(线段树优化dp)
题意 题目链接:https://www.nowcoder.com/acm/contest/91/H 来源:牛客网 题解 设l[i]l[i]l[i]为向左推第iii个骨牌最远能影响到的骨牌的编号,r[i ...
- CF 474E Pillars(线段树优化DP)
CF 474E Pillars 题目描述 Marmot found a row with n n n pillars. The i i i -th pillar has the height of h ...
- hdu 4521(线段树优化dp)
小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Pro ...
- AtCoder Regular Contest 085 F NRE 线段树优化dp
题意 有长度为n初始全为0的数组A和仅由0和1组成的数组B.现在给出m个区间,每次可以选择某个区间[l,r],使得A数组下标在[l,r]之间的元素变为1.问A和B最小不同位置数量是多少. n,m< ...
- [ZJOI2010] 基站选址(线段树优化dp)
problem luogu-P2605 solution 首先,肯定都能想到最暴力的 dpdpdp. dpi,j:idp_{i,j}:idpi,j:i 个村庄为止一共选了 jjj 个基站,且第 ii ...
- CodeForces - 960F[动态开点线段树优化dp]详解
题意:给一张有向图,每条边有边权与编号,求一条最长的路径,这条路径的边权与编号都是递增的.(编号指输入顺序) 首先我们回忆一下普通得LIS得做法:就是dp[i]以第i个结尾得最长上升子序列的长度,那么 ...
- CF834D. The Bakery(线段树优化dp 决策单调性优化dp)
linkkkkk 题意: 将一个长度为 n 的序列分为 m段,使得总价值最大. 一段区间的价值表示为区间内不同数字的个数. n≤35000,m≤50 思路: 考虑朴素的dpdpdp方程:dp[i][j ...
- BZOJ2131 免费的馅饼【线段树优化DP】
Input 第一行是用空格隔开的二个正整数,分别给出了舞台的宽度W(1到10^8之间)和馅饼的个数n(1到10^5). 接下来n行,每一行给出了一块馅饼的信息.由三个正整数组成,分别表示了每个馅饼落到 ...
- 【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)
题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm 来源:牛客网 Given a maze with N rows an ...
最新文章
- u-boot中filesize环境变量【转载】
- python上海培训哪里比较好-python培训班上海哪里比较好?
- [Java] System.arraycopy 数组复制
- MSB6006: “cmd.exe”已退出,代码为 3.
- docker mysql总是退出_docker 安装 mysql
- Comcast以纯文本泄露客户Wi-Fi登录信息,立即更改密码
- Cortex-M系列处理器指令集区别详解
- poj2406(kmp循环节)
- JMeter脚本录制-快速上手篇
- 山东大学计算机文化复习纲要
- 2016.12.30非线性优化计算方法1
- FPGA之JESD204B接口——总体概要 首片
- 德勤,普华永道,安永,毕马威这四大会计师事务所,有什么区别
- android+背景虚化,android背景虚化
- Google Chrome最强鼠标手势插件面世
- 病理与病理生理学【3】
- axios的并发请求和 排队请求
- 【Python实现】微信防撤回
- 模拟城市我是市长服务器维护多久,《模拟城市:我是市长》教你一招渡过新手困难期...
- php拓展so,PHP扩展开发之动态加载so模块与静态重编译PHP(上)-Go语言中文社区...
热门文章
- SAP CRM WebClient UI上分销渠道点击展开按钮后执行了哪些逻辑
- 一个简单的例子教会您使用javap
- python练手_Python数据分析练手项目
- pc端汽车obd软件下载?_【软件】PandaOCR:PC端图片转文字识别软件
- 小程序素材抓取软件_如何抓取微信小程序的数据?
- python目标检测答案_你好,这里有一份2019年目标检测指南
- 美团flutter_ggtalk 聊聊跨平台:后起之秀 Flutter
- 7-37 组个最小数 (20分)_波音737高度计上蹊跷的“8英尺”,09年土耳其航空1951号航班空难...
- vs及番茄助手快捷键使用介绍
- qmake 没有生成.o文件_qmake实用变量