斜率优化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. JAVA_JNI字段描述符“([Ljava/lang/String;)V”(Android)

    JNI字段描述符"([Ljava/lang/String;)V "([Ljava/lang/String;)V" 它是一种对函数返回值和参数的编码.这种编码叫做JNI字段 ...

  2. 使用node+puppeteer+express搭建截图服务

    使用node+puppeteer+express搭建截图服务 转载请注明出处https://www.cnblogs.com/funnyzpc/p/14222807.html 写在之前 一开始我们的需求 ...

  3. Mono for android,Xamarin点击事件的多种写法

    (一)原本java的写法(相信很多是学过java的): 需要实现接口View.IOnClickListener,最好也继承类:Activity,因为View.IOnClickListener接口又继承 ...

  4. spark:distinct算子实现原理

    distinct的底层使用reducebykey巧妙实现去重逻辑 //使用reduceByKey或者groupbykey的shuffle去重思想rdd.map(key=>(key,null)). ...

  5. 性能超四倍的高性能.NET二进制序列化库

    二进制序列化在.NET中有很多使用场景,如我们使用分布式缓存时,通常将缓存对象序列化为二进制数据进行缓存,在ASP.NET中,很多中间件(如认证等)也都是用了二进制序列化. 在.NET中我们通常使用S ...

  6. 洛谷 P4396 [AHOI2013]作业

    题目描述 题目传送门 分析 因为询问是关于区间的,并且没有强制在线,所以能用莫队解决 但是还要支持查询区间内大于等于 \(a\),小于等于 \(b\) 的数的个数和数值的个数 所以还要套一个数据结构 ...

  7. 白日梦的Elasticsearch笔记(一)基础篇

    目录 一.导读 1.1.认识ES 1.2.安装.启动ES.Kibana.IK分词器 二.核心概念 2.1.Near Realtime (NRT) 2.2.Cluster 2.3.Node 2.4.In ...

  8. 【JavaWeb】JavaScript 基础

    JavaScript 基础 事件 事件是指输入设备与页面之间进行交互的响应. 常用的事件: onload 加载完成事件:页面加载完成之后,常用于页面 js 代码初始化操作: onclick 单击事件: ...

  9. Vue基础语法与指令

    项目初始化 用vscode打开终端,输入npm init -y生成package.json 然后安装vue npm install vue 需要注意的是,我遇到了这个问题 出现原因:文件夹名和生成的p ...

  10. python学习笔记 | selenium各浏览器驱动下载地址

    Chrome http://chromedriver.storage.googleapis.com/index.html 不同的Chrome的版本对应的chromedriver.exe 版本也不一样, ...