斜率优化DP:DP的一种优化形式,主要用于优化如下形式的DP

f[i]=f[j]+x[i]*x[j]+...

学习可以参考下面的博客:

https://www.cnblogs.com/Xing-Ling/p/11210179.html

https://blog.csdn.net/xiang_6/article/details/81450647

我的做法结合了这两种方案。

首先,用代数法求出进行状态更新的条件。

然后,判断上凸还是下凸。

在下一步,求出斜率,用于把起始且并不优的状态淘汰。

最后,就可以写代码了

主要题目:

loj10188装箱游戏

 1 #include<bits/stdc++.h>
2 #define rll register long long
3 using namespace std;
4 const int maxn=5e7+10;
5 typedef long long ll;
6 ll sum[maxn],f[maxn],q[maxn];
7 ll n,l,h=1,t=0;
8
9 inline ll min(rll a,rll b){return a<b?a:b;}
10 inline ll X(rll i){return sum[i]+i;}
11 inline ll Y(rll i){return f[i]+(sum[i]+i+1+l)*(sum[i]+i+1+l);}
12 inline long double xl(rll a,rll b){return (long double)(Y(b)-Y(a))/(X(b)-X(a));}
13
14 int main()
15 {
16 scanf("%lld%lld",&n,&l);
17 for(ll i=1;i<=n;++i)
18 {
19 scanf("%lld",sum+i);
20 sum[i]+=sum[i-1];
21 }
22 q[++t]=0;
23 for(ll i=1;i<=n;++i)
24 {
25 while(h<t && xl(q[h],q[h+1])<=2*(sum[i]+i))++h;
26 int j=q[h];
27 f[i]=f[j]+(sum[i]-sum[j]+i-j-1-l)*(sum[i]-sum[j]+i-j-1-l);
28 while(h<t && xl(q[t],i)<=xl(q[t-1],q[t]))t--;
29 q[++t]=i;
30 }
31 cout<<f[n];
32 return 0;
33 }

loj10189仓库建设

 1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn = 1e6 + 10;
5 ll n;
6 ll x[maxn], sum[maxn], s[maxn], c[maxn], f[maxn];
7 ll tail, head, q[maxn];
8 inline ll X(ll a) { return sum[a]; }
9 inline ll Y(ll a) { return f[a] + s[a]; }
10 inline long double xl(ll a, ll b) { return (long double)(Y(b) - Y(a)) / (X(b) - X(a)); }
11
12 int main() {
13 scanf("%lld", &n);
14 for (ll p, i = 1; i <= n; ++i) {
15 scanf("%lld%lld%lld", x + i, &p, c + i);
16 sum[i] = sum[i - 1] + p;
17 s[i] = s[i - 1] + p * x[i];
18 }
19 tail = 0, head = 1;
20 q[++tail] = 0;
21 for (ll i = 1; i <= n; ++i) {
22 while (tail > head && xl(q[head], q[head + 1]) <= x[i]) ++head;
23 int j = q[head];
24 f[i] = f[j] + x[i] * (sum[i] - sum[j]) - s[i] + s[j] + c[i];
25 while (tail > head && xl(q[tail], i) <= xl(q[tail - 1], q[tail])) --tail;
26 q[++tail] = i;
27 }
28 cout << f[n];
29 return 0;
30 }

loj10190特别行动队

 1 #include <bits/stdc++.h>
2 using namespace std;
3 const int maxn = 1e6 + 10;
4 typedef long long ll;
5 ll q[maxn], h = 1, t = 0;
6 ll n, a, b, c, s[maxn], f[maxn];
7 inline ll X(ll i) { return s[i]; }
8 inline ll Y(ll i) { return f[i] + a * s[i] * s[i] - b * s[i]; }
9 inline long double xl(ll a, ll b) { return (long double)(Y(b) - Y(a)) / (X(b) - X(a)); }
10 int main() {
11 scanf("%lld%lld%lld%lld", &n, &a, &b, &c);
12 for (int i = 1; i <= n; ++i) {
13 scanf("%lld", s + i);
14 s[i] += s[i - 1];
15 }
16 q[++t] = 0;
17 for (int i = 1; i <= n; ++i) {
18 while (t > h && xl(q[h], q[h + 1]) >= 2 * a * s[i]) ++h;
19 int j = q[h];
20 f[i] = f[j] + a * (s[i] - s[j]) * (s[i] - s[j]) + b * (s[i] - s[j]) + c;
21 while (t > h && xl(q[t - 1], q[t]) <= xl(q[t], i)) --t;
22 q[++t] = i;
23 }
24 cout << f[n];
25 return 0;
26 }

loj10191打印文章

 1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn = 5e5 + 10;
5 ll n, m;
6 ll s[maxn], f[maxn];
7 ll h, t, q[maxn];
8 inline ll X(ll i) { return s[i]; }
9 inline ll Y(ll i) { return f[i] + s[i] * s[i]; }
10 // inline long double xl(ll a,ll b){return (long double)(Y(b)-Y(a))/(X(b)-X(a));}
11 int main() {
12 while (scanf("%lld%lld", &n, &m) == 2) {
13 memset(s, 0, sizeof s);
14 memset(f, 0, sizeof f);
15 memset(q, 0, sizeof q);
16 h = 1, t = 0;
17 for (int i = 1; i <= n; ++i) {
18 scanf("%lld", s + i);
19 s[i] += s[i - 1];
20 }
21 q[++t] = 0;
22 for (int i = 1; i <= n; ++i) {
23 while (h < t && Y(q[h + 1]) - Y(q[h]) <= 2 * s[i] * (X(q[h + 1]) - X(q[h]))) ++h;
24 ll j = q[h];
25 f[i] = f[j] + (s[i] - s[j]) * (s[i] - s[j]) + m;
26 while (h < t &&
27 (Y(q[t]) - Y(q[t - 1])) * (X(i) - X(q[t])) >= (Y(i) - Y(q[t])) * (X(q[t]) - X(q[t - 1])))
28 --t;
29 q[++t] = i;
30 }
31 printf("%lld\n", f[n]);
32 }
33 return 0;
34 }

loj10192锯木厂选址

 1 #include <bits/stdc++.h>
2 using namespace std;
3 const int maxn = 2e5 + 10;
4 typedef long long ll;
5 ll n, dis[maxn], w[maxn], sw[maxn], swd[maxn], f[maxn][2];
6 ll h = 1, t, q[maxn];
7
8 inline ll x(ll i) { return sw[i]; }
9 inline ll y(ll i) { return f[i][0] + swd[i]; }
10
11 int main() {
12 scanf("%lld", &n);
13 for (ll d, i = 1; i <= n; ++i) {
14 scanf("%lld%lld", w + i, &d);
15 dis[i + 1] = dis[i] + d;
16 sw[i] = sw[i - 1] + w[i];
17 swd[i] = swd[i - 1] + w[i] * dis[i];
18 }
19 sw[n + 1] = sw[n];
20 swd[n + 1] = swd[n];
21 for (ll i = 2; i <= n; ++i) f[i][0] = dis[i] * sw[i] - swd[i];
22 q[++t] = 1;
23 for (ll i = 2; i <= n; ++i) {
24 while (h < t && y(q[h + 1]) - y(q[h]) <= dis[i] * (x(q[h + 1]) - x(q[h]))) ++h;
25 ll j = q[h];
26 f[i][1] = f[j][0] + dis[i] * (sw[i] - sw[j]) - (swd[i] - swd[j]);
27 while (h < t &&
28 (y(q[t]) - y(q[t - 1])) * (x(i) - x(q[t])) >= (y(i) - y(q[t])) * (x(q[t]) - x(q[t - 1])))
29 --t;
30 q[++t] = i;
31 }
32 ll ans = (ll)1 * 100000000 * 100000000;
33 for (int i = 1; i <= n; ++i)
34 if (ans > f[i][1] + dis[n + 1] * (sw[n + 1] - sw[i]) - (swd[n + 1] - swd[i]))
35 ans = f[i][1] + dis[n + 1] * (sw[n + 1] - sw[i]) - (swd[n + 1] - swd[i]);
36 cout << ans;
37
38 return 0;
39 }

loj10184任务安排1

 1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn = 5e3 + 10;
5 ll n, s;
6 ll f[maxn], sc[maxn], st[maxn];
7
8 int main() {
9 scanf("%lld%lld", &n, &s);
10 for (int i = 1; i <= n; ++i) {
11 scanf("%lld%lld", st + i, sc + i);
12 st[i] += st[i - 1];
13 sc[i] += sc[i - 1];
14 }
15 for (int i = n; i > 0; --i) {
16 f[i] = (st[n] + s) * (sc[n] - sc[i - 1]);
17 for (int j = i + 1; j <= n; ++j) {
18 if (f[i] > f[j] + st[j - 1] * (sc[j - 1] - sc[i - 1]) + (sc[n] - sc[i - 1]) * s)
19 f[i] = f[j] + st[j - 1] * (sc[j - 1] - sc[i - 1]) + (sc[n] - sc[i - 1]) * s;
20 }
21 }
22 cout << f[1];
23 return 0;
24 }

loj10185任务安排2

 1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn = 1e4 + 10;
5 ll n, s;
6 ll f[maxn], sc[maxn], st[maxn];
7
8 int main() {
9 scanf("%lld%lld", &n, &s);
10 for (int i = 1; i <= n; ++i) {
11 scanf("%lld%lld", st + i, sc + i);
12 st[i] += st[i - 1];
13 sc[i] += sc[i - 1];
14 }
15 for (int i = n; i > 0; --i) {
16 f[i] = (st[n] + s) * (sc[n] - sc[i - 1]);
17 for (int j = i + 1; j <= n; ++j) {
18 if (f[i] > f[j] + st[j - 1] * (sc[j - 1] - sc[i - 1]) + (sc[n] - sc[i - 1]) * s)
19 f[i] = f[j] + st[j - 1] * (sc[j - 1] - sc[i - 1]) + (sc[n] - sc[i - 1]) * s;
20 }
21 }
22 cout << f[1];
23 return 0;
24 }

一本通提高篇——斜率优化DP的更多相关文章

  1. 【笔记篇】斜率优化dp(一) HNOI2008玩具装箱

    斜率优化dp 本来想直接肝这玩意的结果还是被忽悠着做了两道数论 现在整天浑浑噩噩无心学习甚至都不是太想颓废是不是药丸的表现 各位要知道我就是故意要打删除线并不是因为排版错乱 反正就是一个del标签嘛并 ...

  2. 总结-一本通提高篇&算竞进阶记录

    当一个人看见星空,就再无法忍受黑暗 为了点亮渐渐沉寂的星空 不想就这样退役 一定不会鸽の坑 . 一本通提高篇 . 算竞进阶 . CDQ & 整体二分 . 平衡树 . LCT . 字符串 . 随 ...

  3. 蒟蒻关于斜率优化DP简单的总结

    斜率优化DP 题外话 考试的时候被这个玩意弄得瑟瑟发抖 大概是yybGG的Day4 小蒟蒻表示根本不会做..... 然后自己默默地搞了一下斜率优化 这里算是开始吗?? 其实我讲的会非常非常非常简单,, ...

  4. bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

    题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...

  5. bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

    题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...

  6. [BZOJ3156]防御准备(斜率优化DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP

  7. 【BZOJ-1096】仓库建设 斜率优化DP

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3719  Solved: 1633[Submit][Stat ...

  8. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  9. BZOJ 3156: 防御准备 斜率优化DP

    3156: 防御准备 Description   Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...

随机推荐

  1. (数据科学学习手札101)funcy:Python中的函数式编程百宝箱

    本文示例文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 我们在使用Python完成日常任务时,经常会遇到 ...

  2. 浅入kubernetes(1):Kubernetes 入门基础

    目录 Kubernetes 入门基础 Introduction basic of kubernetes What Is Kubernetes? Components of Kubernetes Kub ...

  3. 阿里技术专家详解 Dubbo 实践,演进及未来规划

    Dubbo 整体介绍 Dubbo 是一款高性能,轻量级的 Java RPC 框架.虽然它是以 Java 语言来出名的,但是现在我们生态里面已经有 Go.Python.PHP.Node.JS 等等语言. ...

  4. 关于BackTop按钮的实现

    今天在处理,首页面的制作的时候,在实现backtop按键的时候,有些思路,作为记录. 功能为,点击backtop即可,立马跳到首页的最上面,且backtop只有在页面后1/2处才显示出来. 首先,我们 ...

  5. MyArray框架搭建与实现

    #include<iostream> using namespace std; template<class T> class MyArray { public: //构造函数 ...

  6. 一个轻量级的.Net Core微服务快速开发的轮子

    前言     Adnc是一个轻量级的.Net Core微服务快速开发框架,同时也可以应用于单体架构系统的开发.框架基于JWT认证授权.集成了一系列微服务配套组件,代码简洁.易上手.学习成本低.开箱即用 ...

  7. mysql plugin

    mysql plugin 概要 mysql可以通过启动参数,系统命令mysql_install,mysql命令install plugin来加载指定的插件 mysql的存储引擎被设计成插件式,可以根据 ...

  8. 在Docker下搭建MySQL双主双重集群(单机展示,与多机原理一致)

    前言 Docker的安装部署&在Docker下MySQL的安装与配置 https://www.cnblogs.com/yumq/p/14253360.html 在Docker进行单机主从复制M ...

  9. NOIP初赛篇——07信息编码表示

    一.基本概念 编码 ​ 计算机要处理的数据除了数值数据以外,还有各类符号.图形.图像和声音等非数值数据.而计算机只能识别两个数字0,1.要使计算机能处理这些信息,首先必须要将各类信息转换成0与1表示的 ...

  10. 配置Oracle数据库和监听随Linux系统自启动【转】

     配置Oracle数据库和监听随Linux系统自启动     在某些情况下需要在Linux操作系统上提供一种无人值守的随机启动Oracle的功能,目的也许仅仅是为了帮助那些对Oracle细节非常不关心 ...