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

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

 (题目链接)

题意

  给出n个防御节点,每个节点有两种选择,可以花费a[i]建立一个防御塔,或者放置一个木偶,木偶的花费为到右端第一个防御塔的距离。求最少花费。

Solution

  容易写出dp方程:$${f[i]=Min(f[j]+\frac{(i-j)*(i-j-1)}{2})}$$

  其中${f[i]}$表示在${i}$处放置防御塔,前${i}$个节点已经完成防御所需要的最少花费。

  易证决策单调性,划出斜率式:$${i>=\frac{(2*f[j]+j+j*j)-(2*f[k]+k+k*k)}{2*(j-k)}}$$

  其中${j<k<i}$。

细节

  斜率里面${j*j}$以及${k*k}$记得开long long,用一个错的程序拍了好久→_→。。

代码

// bzoj3156#include
#include
#include
#include
#include
#include
#define LL long long#define MOD 100000000#define inf 2147483640#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;const int maxn=1000010;LL a[maxn],q[maxn],n;LL f[maxn];double slope(LL j,LL k) { return ((2.0*f[j]+j+j*j)-(2.0*f[k]+k+k*k))/(2.0*(j-k));}int main() { scanf("%lld",&n); for (int i=1;i<=n;i++) scanf("%lld",&a[i]); int l=1,r=1;q[1]=0; for (int i=1;i<=n;i++) { while (l
=slope(q[l],q[l+1])) l++; f[i]=f[q[l]]+(i-q[l])*(i-q[l]-1)/2+a[i]; while (l
slope(q[r],i)) r--; q[++r]=i; } //for (int i=1;i<=n;i++) printf("%d : %lld\n",i,f[i]); printf("%lld",f[n]); return 0;}

  

转载于:https://www.cnblogs.com/MashiroSky/p/6005994.html

你可能感兴趣的文章
noip模拟赛 寻宝之后
查看>>
ZOJ2833*(并查集)
查看>>
外连接简要总结
查看>>
第一次作业-准备篇
查看>>
【C++】继承时构造函数和析构函数
查看>>
opencv源代码之中的一个:cvboost.cpp
查看>>
swift
查看>>
pycharm 快捷键
查看>>
Linux常用命令
查看>>
.net中的设计模式---单例模式
查看>>
安装程序工具 (Installutil.exe)22
查看>>
如何简单解释 MapReduce算法
查看>>
从 0 到 1 实现 React 系列 —— 1.JSX 和 Virtual DOM
查看>>
面向接口编程详解(二)——编程实例
查看>>
解决java.lang.NoClassDefFoundError: org/apache/log4j/Level
查看>>
端口号
查看>>
mysql for macOS安装
查看>>
jquery与checkbox的checked属性的问题
查看>>
HDU5092——Seam Carving(动态规划+回溯)(2014上海邀请赛重现)
查看>>
java 格式化字符串
查看>>