HDU3507 Print Article(斜率优化DP)
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 16213 Accepted Submission(s): 4992
Problem Description
Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it to print articles. But it is too old to work for a long time and it will certainly wear and tear, so Zero use a cost to evaluate this degree. One day Zero want to print an article which has N words, and each word i has a cost Ci to be printed. Also, Zero know that print k words in one line will cost
M is a const number. Now Zero want to know the minimum cost in order to arrange the article perfectly.
Input
There are many test cases. For each test case, There are two numbers N and M in the first line (0 ≤ n ≤ 500000, 0 ≤ M ≤ 1000). Then, there are N numbers in the next 2 to N + 1 lines. Input are terminated by EOF.
Output
A single number, meaning the mininum cost to print the article.
Sample Input
5 5 5 9 5 7 5
Sample Output
230
Author
Xnozero
Source
2010 ACM-ICPC Multi-University Training Contest(7)——Host by HIT
Recommend
zhengfeng | We have carefully selected several similar problems for you: 3506 3501 3504 3505 3498
比较裸的斜率优化。
以前用的是斜截式推,现在改用求决策单调性的方式推了,
后者虽然计算量大,但是无脑一些
推出来之后维护一个上凸壳
推荐一篇写的非常好的博客
https://www.cnblogs.com/orzzz/p/7885971.html
不知道为啥不能写成除法的形式。。
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;
int N, M, a[MAXN], s[MAXN], f[MAXN], q[MAXN];
int X(int x) {
return s[x];
}
int Y(int x) {
return f[x] + s[x] * s[x];
}
int check(int x, int y, int i) {
return (Y(y) - Y(x)) <= (X(y) - X(x)) * 2 * s[i];
}
int check2(int xx1, int yy1, int xx2, int yy2) {
return ((Y(yy1) - Y(xx1)) * (X(yy2) - X(xx2))) >= ((Y(yy2) - Y(xx2)) * (X(yy1) - X(xx1)));
}
/*int slope(int x, int y) {
return (Y(y) - Y(x)) / (X(y) - X(x));
}*/
int main() {
//freopen("a.in", "r", stdin);
while(scanf("%d %d", &N, &M) != EOF) {
memset(f, 0, sizeof(f));
for(int i = 1; i <= N; i++) scanf("%d", &a[i]), s[i] = s[i - 1] + a[i];
int h = 0, t = 0;
for(int i = 1; i <= N; i++) {
// if(h < t) printf("%lf %lfn", slope(q[h], q[h + 1]), (double)2 * s[i]);
while(h < t && check(q[h], q[h + 1], i)) h++;
f[i] = (f[q[h]] + (s[i] - s[q[h]]) * (s[i] - s[q[h]]) + M);
while(h < t && check2(q[t - 1], q[t], q[t], i)) t--;
q[++t] = i;
}
printf("%dn", f[N]);
}
return 0;
}
- Python运用蒙特卡洛算法模拟植物生长
- (57) 二进制文件和字节流 / 计算机程序的思维逻辑
- 真正的 Tornado 异步非阻塞
- (58) 文本文件和字符流 / 计算机程序的思维逻辑
- Python爬虫—破解JS加密的Cookie
- Python通过抓包和使用cookie爬取微博完全讲解
- (50) 剖析EnumMap / 计算机程序的思维逻辑
- 认识九大经典sql模式
- 构建一个pip安装的车辆路径显示的Python包
- 如何编写复杂sql
- Python机器学习工具:Scikit-Learn介绍与实践
- (51) 剖析EnumSet / 计算机程序的思维逻辑
- mysql性能优化的几条重要建议
- Python爬虫抓取知乎所有用户信息
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法