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. GitHub搭建个人主页

    GitHub搭建个人主页 1.注册登录GitHub 2.新建仓库 新建一个名为"username.github.io",其中username为你的用户名,仓库必须为公有类型,私有仓 ...

  2. Java创建线程的三种形式的区别以及优缺点

    1.实现Runnable,Callable Callable接口里定义的方法有返回值,可以声明抛出异常. 继承Callable接口实现线程 class ThreadCall implements Ca ...

  3. AJ学IOS(28)UI之Quartz2D简单介绍

    AJ分享,必须精品 iOS开发UI篇—Quartz2D简单介绍 什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : ...

  4. 选择IT行业的自我心得,希望能帮助到各位!(五)

    相信很多小伙伴,在看完之前的一二三四,也是我一路走来,走走停停,走走停停,有快乐,也有伤悲,毕竟这就是人生嘛,人生不起起伏伏怎么才能体验刺激的快感,也让我从一个小男孩净化成清高浮躁的青少年,在从而让我 ...

  5. python的pip怎样更新包 + pip的help翻译

    1.pip下载安装 pip下载 进入https://pypi.python.org/pypi/pip,下载 .tar.gz压缩包 Linux安装pip # tar -xzvf pip-1.5.4.ta ...

  6. 在Python中该如何实现Java的重写与重载

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:清风python PS:如有需要Python学习资料的小伙伴可以加点击 ...

  7. L26 使用卷积及循环神经网络进行文本分类

    文本情感分类 文本分类是自然语言处理的一个常见任务,它把一段不定长的文本序列变换为文本的类别.本节关注它的一个子问题:使用文本情感分类来分析文本作者的情绪.这个问题也叫情感分析,并有着广泛的应用. 同 ...

  8. S - Primitive Primes CodeForces - 1316C 数学

    数学题 在f(x)和g(x)的系数里找到第一个不是p的倍数的数,然后相加就是答案 为什么? 设x1为f(x)中第一个不是p的倍数的系数,x2为g(x)...... x1+x2前的系数为(a[x1+x2 ...

  9. 格式化启动盘win10

    我这个(U盘)磁盘被分成了两个区,不能直接格式化 第一步: 第二步: 删除完了之后,选择格式化,ok. 说明:格式化时要选择系统. 常规NTFS  缺点:老设备,比如打印机,监控机识别不了. FAT系 ...

  10. java 一维数组的总结笔记

    数组 1. 一位数组的声明方式 type[] array Name 或 type arrayName[];(推荐使用第二种) 错误的声明方式 //int[5] intErrorArray;错误的 // ...