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

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

3156: 防御准备

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 2361  Solved: 997
[ ][ ][ ]

Description

 

 

Input

第一行为一个整数N表示战线的总长度。

第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai。

Output

共一个整数,表示最小的战线花费值。

Sample Input

10
2 3 1 5 4 5 6 3 1 2

Sample Output

18

HINT

1<=N<=10^6,1<=Ai<=10^9

Source

分析:为了方便处理,将a序列翻转过来,那么题目就变成了从左往右处理.

   首先很容易能想到这道题要用到斜率优化,why? 想象一下,枚举一个点i,如果当前点y要放木偶,总得在前面找一个位置放守望塔吧,那么这就是O(n^2)的了,朴素dp的复杂度都是如此,需要对此优化,如何优化,那就是斜率dp咯.

   我一开始想的状态是f[i][0/1]表示前i个位置中,第i个位置放守望塔还是木偶的最小花费值. 可以转移,但这不是斜率优化的那种式子啊......

   斜率优化要求一维的状态,那我的后面一个状态能不能去掉呢?如果令f[i]表示前i个位置中,第i个位置放守望塔的最小化费值,可以枚举前面一个放守望塔的位置j,在j+1 到 i-1之间都放木偶,这个答案是能够计算出来的.

   f(i) = min{f(j) + sum[i - 1] - sum[j] - (i - 1 - j) * d[j] + a[i]}.  d[i]表示i到1的距离,sum[i]表示d数组的前缀和,a[i]表示建守望塔的花费.

   然后就是斜率优化的常规套路了. 注意这里要求min,求的是上凸壳,别弄反了!

 

#include 
#include
#include
#include
using namespace std;typedef long long ll;const ll maxn = 1000010;ll n,a[maxn],l,r,f[maxn],q[maxn],sum[maxn],d[maxn],ans;ll K(ll i){ return -d[i];}ll B(ll i){ return i * d[i] + f[i] - sum[i];}ll Y(ll i,ll j){ return K(i) * (j - 1) + B(i);}bool cmp(ll y1,ll y2,ll y3){ ll temp1 = (K(y1) - K(y3)) * (B(y2) - B(y1)); ll temp2 = (K(y1) - K(y2)) * (B(y3) - B(y1)); return temp1 >= temp2;}int main(){ scanf("%lld",&n); for (ll i = 1; i <= n; i++) scanf("%lld",&a[i]); for (int i = 1, j = n; i <= j; i++,j--) swap(a[i],a[j]); d[1] = 0; for (ll i = 2; i <= n; i++) d[i] = d[i - 1] + 1; for (ll i = 1; i <= n; i++) sum[i] = sum[i - 1] + d[i]; f[1] = a[1]; q[r] = 1; for (ll i = 2; i <= n; i++) { while (l < r && Y(q[l],i) >= Y(q[l + 1],i)) l++; f[i] = Y(q[l],i) + sum[i - 1] + a[i]; while (l < r && cmp(i,q[r - 1],q[r])) r--; q[++r] = i; } ans = f[n]; for (ll i = 1; i < n; i++) ans = min(ans,f[i] + sum[n] - sum[i] - d[i] * (n - i)); printf("%lld\n",ans); return 0;}

 

 

 

转载于:https://www.cnblogs.com/zbtrs/p/8474541.html

你可能感兴趣的文章
Linux之ssh服务介绍
查看>>
排序:冒泡排序
查看>>
Java中instanceof关键字的用法总结
查看>>
引用类型-Function类型
查看>>
(转)Android 仿订单出票效果 (附DEMO)
查看>>
数据库多张表导出到excel
查看>>
微信小程序去除button默认样式
查看>>
Where does Visual Studio look for C++ Header files?
查看>>
Java打包可执行jar包 包含外部文件
查看>>
Windows Phone开发(37):动画之ColorAnimation
查看>>
js中escape,encodeURI,encodeURIComponent 区别(转)
查看>>
sass学习笔记-安装
查看>>
Flask (二) cookie 与 session 模型
查看>>
修改添加网址的教程文件名
查看>>
[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)
查看>>
裁剪图片
查看>>
数据结构实习 problem L 由二叉树的中序层序重建二叉树
查看>>
VS中展开和折叠代码
查看>>
如何确定VS编译器版本
查看>>
设置PL/SQL 快捷键
查看>>