斜率优化学会以后好像也不是那么难嘛。。。

以BZOJ1911为例

->在洛谷上查看

设\(s_i\)为前\(i\)个元素的前缀和,\(f_i\)为dp数组。

\(f_i=max\{f_j+a(s_i-s_j)^2+b(s_i-s_j)+c\}\)

\(f_i=max\{f_j+a(s_i^2-2s_is_j+s_j^2)+b(s_i-s_j)+c\}\)

\(f_i=max\{f_j+as_i^2-2as_is_j+as_j^2+bs_i-bs_j+c\}\)

\(=max\{f_j-2as_js_i+as_j^2-bs_j\}+as_i^2+bs_i+c\)

将\(max\)内部变为直线解析式。

令\(k=-2as_j\),\(b=f_j+as_j^2-bs_j\),自变量\(x\)。

原式\(=kx+b\)

由于\(-5\le a\le-1\),\(s_i\)单调递增

所以\(k=-2as_i>0\)且单调递增,即斜率递增。

我们的目标是找到当\(x=s_i\)时,\(y\)最大的一条直线。

如图是目前加入队列的直线,绿色直线为们查找的位置。

紫色部分的边缘便是每个位置的最大值,是一个凸壳。

由于斜率是递增的,所以蓝色直线必然在队尾。

发现我们找到的最大值在红线上,由于红线的斜率大于蓝线的斜率,且\(s_i\)递增(即接下来访问的位置都在绿线的右边),所以实际上蓝线代表的j已经不可能更新任何之后的状态了。

于是我们把它弹掉,然后用目前的队尾(就是之前最大值所在的线)更新答案,再把更新好的线加入队列。

但是还需要考虑一种情况。

就是一条直线上没有任何一段在凸壳上,即被原凸壳上的任意两条直线覆盖。

比如我们又加入了一根绿线。

我们发现红线被蓝线和绿线覆盖了,而这条刚刚被覆盖的直线总是加入新的直线之前的队首,并且当它被队首之后的那条直线和新加入的线覆盖,它也被任意两条直线覆盖。

想想为什么。这里不给出证明。

(其实就是懒得想)

那么如何判断两条线覆盖另一条线?

假设\(l_1:k_1x+b_1\),\(l_2:k_2x+b_2\),\(l_3:k_3x+b_3\),并且\(l_1\),\(l_2\)覆盖\(l_3\),\(\color{red}k_1>k_2\),\(\color{red}k_1>k_3\)。

我们可以找到\(l_1\),\(l_2\)的交点,过这个交点作\(l_3\)的平行线\(l_4\),显然\(l_4\)与当前凸壳相切与该点,如果\(l_4\)在\(l_3\)之上说明\(l_3\)不在凸壳上。

其实就是\(l_1\),\(l_2\)交点在\(l_3\)之上。

所以只需要比较这个交点的\(y\)坐标和\(l_3\)在\(x\)坐标相同时的\(y\)值即可。

具体如下:

先求\(l_1\),\(l_2\)交点。

\(k_1x+b_1=k_2x+b_2\)

解得\(x=\frac{b_2-b_1}{k_1-k_2}\),此时\(k_1x+b_1=k_2x+b_2=k_1\frac{b_2-b_1}{k_1-k_2}+b_1\)

\(l_3\)在\(x\)相等时的\(y=k_3\frac{b_2-b_1}{k_1-k_2}+b_3\)

如果交点在\(l_3\)之上,

\(k_1\frac{b_2-b_1}{k_1-k_2}+b_1\ge k_3\frac{b_2-b_1}{k_1-k_2}+b_3\)

\(\frac{b_2-b_1}{k_1-k_2}+\frac{b_1}{k_1}\ge \frac{k_3}{k_1}\frac{b_2-b_1}{k_1-k_2}+\frac{b_3}{k_1}\)

\(\frac{1}{k_3}\frac{b_2-b_1}{k_1-k_2}+\frac{b_1}{k_1k_3}\ge \frac{1}{k_1}\frac{b_2-b_1}{k_1-k_2}+\frac{b_3}{k_1k_3}\)

\(\frac{1}{k_3}\frac{b_2-b_1}{k_1-k_2}-\frac{1}{k_1}\frac{b_2-b_1}{k_1-k_2}\ge \frac{b_3}{k_1k_3}-\frac{b_1}{k_1k_3}\)

\(\frac{k_1-k_3}{k_1k_3}\frac{b_2-b_1}{k_1-k_2}\ge \frac{b_3-b_1}{k_1k_3}\)

\(\frac{b_2-b_1}{k_1-k_2}\ge \frac{b_3-b_1}{k_1-k_3}\)

因为\(k_1>k_2\),\(k_1>k_3\)

\((b_2-b_1)(k_1-k_3)\ge (b_3-b_1)(k_1-k_2)\)

所以满足上式时,\(l_3\)不在凸壳中。

于是就可以写代码了。

code:

#include<bits/stdc++.h>
using namespace std;
int n,v[1000010],s[1000010],q[1000010],l,r;
long long a,b,c,dp[1000010],lk[1000010],lb[1000010],tv;
void scan(int &x){x=0;char c=getchar();while('0'>c||c>'9')c=getchar();while('0'<=c&&c<='9')x=x*10+c-'0',c=getchar();
}
long long val(int i,int x){return lk[i]*x+lb[i];
}
bool cov(int l1,int l2,int l3){//l1,l2 cover l3return (lb[l2]-lb[l1])*(lk[l1]-lk[l3])>=(lb[l3]-lb[l1])*(lk[l1]-lk[l2]);
}
int main(){scanf("%d%lld%lld%lld",&n,&a,&b,&c);for(int i=1;i<=n;i++){scan(v[i]);s[i]=s[i-1]+v[i];}l=r=1;q[1]=0;dp[0]=0;for(int i=1;i<=n;i++){while(l<r&&val(q[l],s[i])<=val(q[l+1],s[i]))l++;dp[i]=val(q[l],s[i])+a*s[i]*s[i]+b*s[i]+c;lk[i]=-2*a*s[i];lb[i]=dp[i]+a*s[i]*s[i]-b*s[i];while(l<r&&cov(i,q[r-1],q[r]))r--;//不能写cov(q[r-1],i,q[r])q[++r]=i;}printf("%lld",dp[n]);return 0;
}

转载于:https://www.cnblogs.com/xryjr233/p/APIO2010.html

[2018.12.4]斜率优化(以[Apio2010]特别行动队为例)相关推荐

  1. 【斜率优化】[APIO2010]特别行动队

    题目 题目描述 你有一支由 nn 名预备役士兵组成的部队,士兵从 11 到 nn 编号,你要将他们拆分成若干特别行动队调入战场.出于默契的考虑,同一支特别行动队中队员的编号应该连续,即为形如 (i, ...

  2. 浅谈斜率优化(例题特别行动队)

    题目描述 你有一支由nnn名预备役士兵组成的部队,士兵从111到nnn编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑,同一支特别行动队中队员的编号应该连续,即为形如(i,i+1,..., ...

  3. bzoj 1911: [Apio2010]特别行动队 -- 斜率优化

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Description Input Output Sample Input 4 ...

  4. BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 4142  Solved: 1964 [Submit][Sta ...

  5. bzoj 1911: [Apio2010]特别行动队 2011-12-26

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 892  Solved: 359 [Submit][Statu ...

  6. 1911: [Apio2010]特别行动队

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 4061  Solved: 1922 [Submit][Sta ...

  7. [APIO2010]特别行动队——[斜率优化DP]

    [题目描述] 你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 n 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑,同一支特别行动队中队员的编号 应该连续,即为形如(i,i+1,. ...

  8. APIO2010 特别行动队 斜率优化DP算法笔记

    做完此题之后 自己应该算是真正理解了斜率优化DP 根据状态转移方程$f[i]=max(f[j]+ax^2+bx+c),x=sum[i]-sum[j]$ 可以变形为 $f[i]=max((a*sum[j ...

  9. 【bzoj1911】[Apio2010]特别行动队 斜率优化dp

    题目描述 输入 输出 样例输入 4 -1 10 -20 2 2 3 4 样例输出 9 题解 斜率优化dp 设f[i]表示前i个士兵的战斗力之和的最大值. 那么有f[i]=f[j]+a*(sum[i]- ...

最新文章

  1. 干货 | 清华大学刘知远 CCL 2018学生研讨会报告(附完整PPT下载)
  2. Mysql源码学习——源码目录结构
  3. 测试时代诚聘软件测试讲师,欢迎有志之士加入!!职位要求:
  4. 834. Sum of Distances in Tree
  5. 快速入门 TensorFlow2 模型部署
  6. amd显卡风扇调节_非公版才是真爱 讯景XFX RX6800 XT海外版显卡评测
  7. 电影特效用到什么计算机知识,后期影视特效处理知识普及
  8. 更改收藏夹路径和桌面路径
  9. 智能陈桥五笔7.8试用编号是多少_如何设计和编写软件测试用例
  10. Google Code 中使用svn工具说明
  11. AE CS6安装教程说明
  12. QQ微信等分享链接时系统提取的标题和图片代码
  13. 微信支付body中文乱码解决方案
  14. 大数据专业学校课程安排 (仅供参考)
  15. 这些优秀的 Spring Cloud 开源软件,你知道的有几个?
  16. GD32F4—RTC闹钟及自动唤醒中断配置详解
  17. RICOH 打印机 打印速度突然变慢
  18. QT QTextEdit富文本插入字体-表格-编号-图片-查找-语法高亮功能
  19. 计算机 调 应用统计,山东工商学院统计学院2020年应用统计专硕调剂信息
  20. 苹果刷机未知错误75_新一轮的测试开始!| 苹果发布 iOS 13.3.1 首个开发者测试版...

热门文章

  1. 我国民用航空器飞行需要哪些条件
  2. linux 服务器安全狗2.3版发布
  3. python投资分析实验报告_Python的实验报告怎么写?
  4. 一次redis诡异的连接超时问题排查与解决
  5. git中配置.gitignore文件
  6. Docker学习记录(到docker-compose)
  7. 基于51单片机的跑步机心率计速度测量系统proteus仿真原理图PCB
  8. 使用MACS2进行差异peak分析
  9. 虚幻4漏光问题解决方法
  10. 《28天玩转TensorFlow2》第13天:TensorFlow2项目实战—基于CNN+RNN和TCN的股票预测