A - Print Article

HDU - 3507

今天刚刚学习了一下斜率dp,感觉还ok,主要就是要推这个斜率,然后利用数据结构来优化。

推荐两篇写的比较好的博客,https://www.cnblogs.com/orzzz/p/7885971.html ----> 这个主要学习这个斜率dp的思路

https://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html ---> 这个主要看代码,中间过程感觉有点问题。

https://blog.csdn.net/qq_37025443/article/details/78986673  --->  这个也建议看看

自己重新理一下这个思路。

sum[i] 表示从1~i 的前缀和

dp[i]表示输到第 i 个字母的最小的花费

所以转移方程很简单 dp[i]=min(dp[j]+(sum[i]-sum[j])^2+M),因为这个j已经输出了,所以下次考虑j+1~i 所以是sum[i]-sum[j] 而不是sum[i]-sum[j-1]

因为这个n有5e5 所有for两次显然会T,这个就可以利用斜率来优化。

令j>k 如果从 j 转移比从k转移更优就需要满足  dp[j]+(sum[i]-sum[j])^2+M<dp[k]+(sum[i]-sum[k])^2+M

上面式子化简之后就是dp[j]+sum[j-1]^2-(dp[k]+sum[k]^2)<2*sum[i]*(sum[j-1]-sum[k])

然后令F[x]=dp[x]-sum[x]^2

所以就是F[j]-F[k]<sum[i]*2*(sum[j]-sum[k]) 而且要满足  j>k

令G[j,k]=(F[j]-F[k])/(2*(sum[j]-sum[k])

所以如果有 i>j>k 那么如果是G[i,j]>G[j,k] 这样就是一个上凹折线,这个肯定不对

G[i,j]<sum[i],那么就是说i点要比j点优,排除j点。

如果G[i,j]>=sum[i],那么j点此时是比i点要更优,但是同时G[j,k]>G[i,j]>sum[i]。这说明还有k点会比j点更优,同样排除j点。

所以一定是下凸的折现,如果不是的就可以排除。

然后对于G[i,j]>G[j,k]

也有三种情况:

1. G[i,j]>sum[t]>G[j,k]   j 比 i 优,j 比 k 优

2. G[i,j]>G[j,k]>sum[t]  j 比 i 优,k比 j 优

3.sum[t]>G[i,j]>G[j,k]  i 比 j 优 ,j比 k 优

所以我们就用单调队列维护<sum[t] 的最大值即可。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 5e5 + ; int que[maxn], dp[maxn];
int sum[maxn];
int n, m; int up(int i,int j)
{
return dp[i] + sum[i] * sum[i] - (dp[j] + sum[j] * sum[j]);
} int down(int i,int j)
{
return * (sum[i] - sum[j]);
} int DP(int i,int j)
{
return dp[j] + (sum[i] - sum[j])*(sum[i] - sum[j]) + m;
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
sum[] = dp[] = ;
for (int i = ; i <= n; i++) scanf("%d", &sum[i]), sum[i] += sum[i - ];
int tail = , head = ;
que[tail++] = ;//因为可能是前面i个全部作为一段才是最小值
for (int i = ; i <= n; i++) {//head+1<tail 保证队列里面至少有两个值
while (head + < tail&&up(que[head + ], que[head]) <= sum[i] * down(que[head + ], que[head])) head++;
dp[i] = DP(i, que[head]);
while (head + < tail&&up(i, que[tail - ])*down(que[tail - ], que[tail - ]) <= up(que[tail - ], que[tail - ])*down(i, que[tail - ])) tail--;
que[tail++] = i;
}
printf("%d\n", dp[n]);
}
return ;
}

斜率dp A - Print Article HDU - 3507的更多相关文章

  1. Print Article hdu 3507 一道斜率优化DP 表示是基础题,但对我来说很难

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  2. Print Article HDU - 3507 -斜率优化DP

    思路 : 1,用一个单调队列来维护解集. 2,假设队列中从头到尾已经有元素a b c.那么当d要入队的时候,我们维护队列的下凸性质, 即如果g[d,c]<g[c,b],那么就将c点删除.直到找到 ...

  3. B - Lawrence HDU - 2829 斜率dp dp转移方程不好写

    B - Lawrence HDU - 2829 这个题目我觉得很难,难在这个dp方程不会写. 看了网上的题解,看了很久才理解这个dp转移方程 dp[i][j] 表示前面1~j 位并且以 j 结尾分成了 ...

  4. hdu 3507 Print Article(斜率优化DP)

    题目链接:hdu 3507 Print Article 题意: 每个字有一个值,现在让你分成k段打印,每段打印需要消耗的值用那个公式计算,现在让你求最小值 题解: 设dp[i]表示前i个字符需要消耗的 ...

  5. HDU 3507 Print Article(DP+斜率优化)

     Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...

  6. DP(斜率优化):HDU 3507 Print Article

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  7. HDU 3507 Print Article(斜率优化DP)

    题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...

  8. HDU 3507 Print Article 斜率优化

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  9. hdu 3507 斜率dp

    不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个 ...

随机推荐

  1. Linux Mint(Ubuntu)如何管理开机自动启动项?

    Linux Mint自带了一个简洁的开机自启管理应用,使用方法也很简单: 依次点击“Menu”==>“控制中心”==>“个人”==>“启动应用程序”,界面如图所示: 上面打勾的就是系 ...

  2. 记一次pgsql中查询优化(子查询)

    记一次pgsql的查询优化 前言 这是一个子查询的场景,对于这个查询我们不能避免子查询,下面是我一次具体的优化过程. 优化策略 1.拆分子查询,将需要的数据提前在cte中查询出来 2.连表查询,直接去 ...

  3. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十三)之Strings

    Immutable Strings Objects of the String class are immutable. If you examine the JDK documentation fo ...

  4. ActiveMQ支持的消息协议

    ActiveMQ支持哪些协议 ActiveMQ支持多种协议传输和传输方式,允许客户端使用多种协议连接ActiveMQ支持的协议:AUTO,OpenWire,AMQP,Stomp,MQTT等Active ...

  5. 解决SpringMVC的乱码问题:CharacterEncodingFilter

    在使用 SpringMVC 框架的过程中,如果前台有包含中文的请求,或者后台有包含中文的响应,有可能会出现乱码的情况.在以前的 Servlet 中,我们使用 request.setCharacterE ...

  6. Windows10 下安装SourceTree 跳过注册 Bitbucket

    前提:安装Git 下载Windows系统可执行文件SourceTreeSetup-3.1.3.exe 双击安装,会出现如下界面: 关闭这个界面 C:\Users\当前用户文件夹\AppData\Loc ...

  7. 资料整理:python接口类

    1开发原则(七大原则) 一:开放封闭原则 二:接口隔离原则(将不同接口对象一一展现出来,分别调用各自的接口,完成各自的功能) 三:依赖倒置原则 高级模块不能依赖低级模块,可以依赖抽象 规范的定义: 高 ...

  8. leetcode-0101 对称二叉树

    题目地址 https://leetcode-cn.com/problems/symmetric-tree/ 1.递归 本题最简单的思路是递归,可以假设两棵一模一样的树在进行镜像对比.他们之间的关系满足 ...

  9. MVC-过滤器-权限认证

    过滤器主要基于特性,aop来实现对MVC管道中插入其他处理逻辑.比如,访问网站,需要检查是否已经登陆,若没登陆跳入登陆界面. 样例: 方法注册 执行效果 当不符合认证时: 上面是方法注册特性.还有类注 ...

  10. Ubuntu创建WiFi:16.0.4

    点击编辑链接,点击桌面状态栏的网络图标 点击增加 类型选择WiFi 名称.SSID,均要填写,模式选择:热点 wifi安全性:选择一个安全模式,这里选的是, wpa 及 wpa2个人 必须说的是:选择 ...