博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[bzoj3156]防御准备
阅读量:6936 次
发布时间:2019-06-27

本文共 1285 字,大约阅读时间需要 4 分钟。

题目大意:给定一个长为$n$的序列,每个点需要放置一个守卫塔或一个木偶,在第$i$个点放置守卫塔的代价为$a_i$,放置木偶的代价为$j-i$,$j$为$i$右边第一个守卫塔,求最小代价。

题解:$O(n^2)$的$DP$显然,$ f_i=\min\limits_{j < i}\{f_j+a_i+1+2+\dots + (i - j - 2) + (i - j - 1)\}$

$$\begin{align*}

f_i&=\min\limits_{j < i}\{f_j+\frac{(i - j)(i - j - 1)}{2} + a_i\}\\
&=\min\limits_{j < i}\{f_j+\frac{i^2-ij-i+ij+j^2+j}{2}+a_i\}
\end{align*}$$

$$把关于i的部分提出来$$

$$f_i=\min\limits_{j < i}\{f_j+\frac{j^2+j}{2}+ij\} + a_i+\frac{i^2-i}{2}$$

$$令y_i=f_i+\frac{i^2+i}{2}$$

$$f_i=\min\limits_{j < i}\{y_j+ij\} + a_i+\frac{i^2-i}{2}$$

$$考虑a和b两个决策,若a<b且b比a优$$

$$\therefore y_b-ib<y_a-ia$$

$$\Rightarrow \frac{y_b-y_a}{b-a}<i$$

然后乱搞就好了

卡点:

 

C++ Code:

#include 
#define int long long#define maxn 1000010using namespace std;int n, a[maxn], f[maxn];int q[maxn], h, t;int y(int x) {return f[x] + (x * (x + 1) >> 1);}double slope(int a, int b) { return 1.0 * (y(b) - y(a)) / (b - a);}signed main() { scanf("%lld", &n); h = t = 0; for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); while (h < t && slope(q[h], q[h + 1]) <= i) h++; int tmp = q[h]; f[i] = y(tmp) - i * tmp + a[i] + (i * (i - 1) >> 1); while (h < t && slope(q[t - 1], q[t]) >= slope(q[t], i)) t--; q[++t] = i; } printf("%lld\n", f[n]); return 0;}

  

转载于:https://www.cnblogs.com/Memory-of-winter/p/9463513.html

你可能感兴趣的文章
SVN如何check out单个文件
查看>>
Winsock IO模式
查看>>
Squid 代理服务器
查看>>
constellio——基于solr的开源搜索引擎系统源码研究(二)
查看>>
求反射向量
查看>>
CSS3 学习+实践(三)
查看>>
hadoop集群搭建
查看>>
基于UDP的IO多路复用一例
查看>>
海量数据处理专题(九)——外排序
查看>>
解决sqlplus的segmentation fault或hang问题
查看>>
企业搜索引擎开发之连接器connector(八)
查看>>
win8下Python学习——搭建web.py框架
查看>>
自动清理手机文件方法
查看>>
【工具类】NetWorkHelper
查看>>
Spring MVC 教程,快速入门,深入分析(转载)
查看>>
财经法规与会计职业道德4
查看>>
php 杂记
查看>>
单元测试同时支持 NUnit/MSTest
查看>>
沟通至上 《高效程序员的45个习惯》读书笔记
查看>>
解决Android中无法搜索联系人的问题
查看>>