题目

为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄做一些防火措施,保障自己、猫、奶牛的生命安全。

农夫约的农庄里有N+1 座建筑,排成了一排,编号为0~N。对于0 <=i < N,建筑i 有w[i]头奶牛居住,与建筑i+1 距离为d[i]。建筑N 已装有消防栓,现在,农夫约决定再给k 个建筑安装消防栓,以减小安全隐患。

当火灾来临时,所有奶牛会从所在建筑开始,向大编号方向逃生,直到遇上第一个消防栓(如果本来就在消防栓处,就不用跑了)。农夫约定义了一个隐患值val:所有奶牛逃生距离之和。

农夫约希望让隐患值尽可能小,需要你给他设计一个好方案。

分析

设 \(f_{i,l}\) 表示做到第 \(i\) 个,已经装了 \(l\) 个安全栓时最小答案

转移时枚举一个 \(j\),为了能快速转移,我们需要一些辅助数组

设 \(g_i\) 表示 \(i\) 之前的所有奶牛到 \(i\) 的总逃生距离

\(s_i,d_i\) 分别表示题中 \(w,d\) 的前缀和

那么 \(f_{i,j} = \min f_{j,l-1}+g_i-g_j-(d_{i-1} - d_{j-1})\times s_j\)

对于 \(j=0\) 是为了不越界特殊处理

由于它是 \(O(n^2k)\) 的,我们还需斜率优化

\(Code\)

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL; const int N = 1e6 + 5 , K = 25;
int n , k , pre[N][K] , q[N];
LL f[N][3] , d[N] , dd[N] , s[N] , g[N]; void print(int p , int k)
{
if (p) print(pre[p][k] , k - 1);
else return;
printf("%d " , p - 1);
}
inline double slope(int x , int y , int l)
{
LL X1 , X2;
if (x == 0) X1 = f[x][l & 1 ^ 1];
else X1 = f[x][l & 1 ^ 1] - g[x] + s[x] * d[x - 1];
if (y == 0) X2 = f[y][l & 1 ^ 1];
else X2 = f[y][l & 1 ^ 1] - g[y] + s[y] * d[y - 1];
return 1.0 * (X1 - X2) / (s[x] - s[y]);
}
inline LL read()
{
LL res = 0;
char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') res = (res << 3) + (res << 1) + ch - '0' , ch = getchar();
return res;
} int main()
{
freopen("life.in" , "r" , stdin);
freopen("life.out" , "w" , stdout);
n = read() , k = read();
for(register int i = 1; i <= n; i++) s[i] = read() , d[i] = dd[i] = read();
for(register int i = 1; i <= n + 1; i++)
s[i] += s[i - 1] , d[i] += d[i - 1] , g[i] = g[i - 1] + s[i - 1] * dd[i - 1]; for(register int i = 0; i <= n + 1; i++)
for(register int j = 0; j <= 1; j++) f[i][j] = 1e17;
f[0][0] = 0; int h , t;
for(register int l = 1; l <= k + 1; l++)
{
q[h = t = 1] = 0;
for(register int i = 1; i <= n + 1; i++)
{
while (h < t && slope(q[h] , q[h + 1] , l) < d[i - 1]) h++;
if (q[h] == 0) f[i][l & 1] = f[q[h]][l & 1 ^ 1] + g[i];
else f[i][l & 1] = f[q[h]][l & 1 ^ 1] + g[i] - g[q[h]] - (d[i - 1] - d[q[h] - 1]) * s[q[h]];
pre[i][l] = q[h];
while (h <= t && slope(q[t - 1] , q[t] , l) > slope(q[t] , i , l)) t--;
q[++t] = i;
}
}
printf("%lld\n" , f[n + 1][(k + 1) & 1]);
print(pre[n + 1][k + 1] , k);
}

最新文章

  1. vs------各种错误解决方法
  2. Markdown 写作工具选择
  3. hihoCoder挑战赛14 -1223
  4. hdu 4640(状压dp)
  5. 如何获取DIV的id
  6. 安装qt5.3.2后,qtcreator在ubuntu 11.04无法启动的问题
  7. Spring中@Transactional用法深度分析
  8. Ruby处理二进制(未完成)
  9. 使用ASP.NET实现Windows Service定时执行任务
  10. [Reactive Programming] Async requests and responses in RxJS
  11. leetcode Combination Sum python
  12. stl 迭代子的失效
  13. shell:监控进程运行状态并自动重启进程
  14. 介绍linux下Source Insight强大代码编辑器sublime_text_3
  15. actor
  16. 轻轻的扩展了一下IEnumerable&lt;T&gt;
  17. idea+scala+spark遇到的一些问题
  18. form表单中的input有哪些类型
  19. INT_MAX (2147483647) 和INT_MIN (-2147483648)溢出
  20. BZOJ_5118_Fib数列2_矩阵乘法+欧拉定理

热门文章

  1. 安装mySql 出现 one more product requirements have not been satisified
  2. 【每日一题】【初始节点初始化,前一个为空】2022年1月7日-NC78 反转链表
  3. Qt VideoMeeting_Intercom师生对讲开发中实际上遇到的一些问题,终于结项了,也照例写一下总结吧。
  4. Qt操作Json小结
  5. python基础(数据库、可视化软件Navicat、python操作MySQL)
  6. 红袖添香,绝代妖娆,Ruby语言基础入门教程之Ruby3基础语法,第一次亲密接触EP01
  7. [深度学习] ncnn编译使用
  8. 20 张图带你全面了解 HTTPS 协议,再也不怕面试问到了!
  9. Java学习记录:2022年1月13日(其二)
  10. YMOI 2019.6.8