斜率DP hdu 3507
One day Zero want to print an article which has N words, and each word i has a cost Ci to be printed. Also, Zero know that print k words in one line will cost
M is a const number.
Now Zero want to know the minimum cost in order to arrange the article perfectly.
大致题意:要打印一长串词语,每个词语有一个对应的打印费用Ci,要给词语分行,一行的总费用记为
,M是给定的常数
要求计算一种分行方案使得总费用最小。
数据规模50万。
分析:首先可以想到枚举上一次断行处,这样可以得到最初的状态转移方程:
,复杂度为O(n^2)。
观察一下数据规模为50万,需要优化。
主要思路是考虑淘汰肯定对最优答案没有贡献的点。
将状态转移方程展开:
(注:公式和图来自BIG YAO学长)

移项可得:


观察到蓝色字体部分只与j有关,绿色字体对给定的i为常量,红色字体部分取最小的时候dp[i]取最小。
将蓝色字体视为y(j),sum[j]视为x(j),问题就转化为对平面上无数个点(x,y),对每一个i,找出一个最优点(x0,y0),使得一条通过该点,斜率为k=2sum[i]的直线的截距最小。
放张图表现一下优化情况:

维护一个队列,即为下凸折线上点的队列,每次寻找最优的j的时候只在队列里的点找。(注意取得最优点的时候相邻的两根折线的斜率对于k=2sum[i]一大一小)
以下具体讨论怎么实现:
i不断向前推进,每次循环做两件事情:
1,找出对于dp[i]最优的上一个断行处j
如果队列上该点i和他后面的那个店形成的斜率小于k=2*sum[i]就头指针+1。
注意由于随i的递增,k=2*sum[i]必然递增,所以出队的点就不需要回来了
2,把i放入队列后就不再需要的点淘汰掉:

一旦出现3个点呈这样,即可淘汰点2,因为:直线经过点4的截距必然小于经过点2的截距,而经过点4的截距必然小于经过点1或点3的截距。
从而经过点2的截距必然小于小1或点3的截距,点2不可能为最优点,可淘汰。

然后把i放入队列(注意sum[i]为严格递增的,所以i个点中最后一个点必然在“外围”,不会被淘汰)
#include<cstdio>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int MAXN=;
long long int dp[MAXN],q[MAXN],sum[MAXN];
int n,m;
inline long long int getdp(int i,int j)
{
return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);
}
inline long long int gety(int x,int y)
{
return dp[x]+sum[x]*sum[x]-dp[y]-sum[y]*sum[y];
}
inline long long int getx(int x,int y)
{
return *sum[x]-*sum[y];
}
int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)==)
{
sum[]=;
rep(i,,n)
{
scanf("%lld",&sum[i]);
sum[i]=sum[i-]+sum[i];
}
dp[]=;
int head,tail;
tail=;
head=;
q[tail]=; //虚拟制造一个点0,若0点最优代表把所有词语分成一行最优
rep(i,,n)
{
while(head+<=tail&&(gety(q[head+],q[head])<=sum[i]*getx(q[head+],q[head]))) head++; //寻找对于i最好的上一次分行的截止点
dp[i]=getdp(i,q[head]);
while(head+<=tail&&gety(i,q[tail])*getx(q[tail],q[tail-])<=gety(q[tail],q[tail-])*getx(i,q[tail])) tail--; //i放入队列后需要淘汰的点
q[++tail]=i; //把i放入队列
}
printf("%lld\n",dp[n]);
}
return ;
}
斜率DP hdu 3507的更多相关文章
- hdu 3507 斜率dp
不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个 ...
- hdu 3507 Print Article(斜率优化DP)
题目链接:hdu 3507 Print Article 题意: 每个字有一个值,现在让你分成k段打印,每段打印需要消耗的值用那个公式计算,现在让你求最小值 题解: 设dp[i]表示前i个字符需要消耗的 ...
- 斜率dp A - Print Article HDU - 3507
A - Print Article HDU - 3507 今天刚刚学习了一下斜率dp,感觉还ok,主要就是要推这个斜率,然后利用数据结构来优化. 推荐两篇写的比较好的博客,https://www.cn ...
- HDU 3507 Print Article(斜率优化DP)
题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...
- HDU 3507 单调队列 斜率优化
斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方 ...
- B - Lawrence HDU - 2829 斜率dp dp转移方程不好写
B - Lawrence HDU - 2829 这个题目我觉得很难,难在这个dp方程不会写. 看了网上的题解,看了很久才理解这个dp转移方程 dp[i][j] 表示前面1~j 位并且以 j 结尾分成了 ...
- HDU 3480 - Division - [斜率DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- HDU 2829 - Lawrence - [斜率DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2829 T. E. Lawrence was a controversial figure during ...
- HDU 2993 - MAX Average Problem - [斜率DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 Consider a simple sequence which only contains p ...
随机推荐
- JQuery学习笔记——层级选择器
JQuery学习笔记--层级选择器 上一篇学习了基础的五种选择,分别是id选择器,class选择器,element选择器,*选择器 和 并列选择器.根据手册大纲,这篇学习的是层级选择器. 选择器: 1 ...
- FreeRTOS——中断管理
1. 只有以“FromISR”或"FROM_ISR"结束的API函数或宏才可以在中断服务函数中使用. 2. 除互斥信号量外,所有类型的信号量都可以调用 xSemaphoreTake ...
- nyoj_2:括号配对问题
模拟栈的操作,很基础的一道题 题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=2 #include<stdio.h> #inc ...
- 大三仍是Linux系统小白的我给大家讲讲学习历程
我与Linux结缘是在大三的时候.我与Linux熟识是在偶然遇到<Linux就该这么学>的时候.因为我是电子信息工程专业,在高年级时开设了嵌入式课程,嵌入式系统是一种专用的计算机系统,作为 ...
- (转)Linux端口nmap和netstat命令
场景:弄不清楚端口和服务的关系,总觉得这个命令很有用但是还不清楚如何使用 1 linux端口与服务 1.1 安全概述 网络传输安全.操作系统安全.应用软件安全构成了整个网络应用的安全:其中应用软件安全 ...
- 【SqlServer系列】集合运算
1 概述 已发布[SqlServer系列]文章如下: [SqlServer系列]SQLSERVER安装教程 [SqlServer系列]数据库三大范式 [SqlServer系列]表单查询 [SqlS ...
- C指针1
//定义:指针是一个特殊的数据类型,指针指向内存中的地址,因此,指针变量存储的是内存中的一个地址 //例子,%p表示打印一个地址,打印p表示打印p指向的地址 //输出结果为0x7fff5fbff7dc ...
- IT人不要一直做技术
我现在是自己做,但我此前有多年在从事软件开发工作,当回过头来想一想自己,觉得特别想对那些初学JAVA/DOT.NET技术的朋友说点心里话,希望你们能从我们的体会中,多少受点启发(也许我说的不好,你不赞 ...
- 【原创】IE11惊现无厘头Crash BUG(三招搞死你的IE11,并提供可重现代码)!
前言 很多人都知道我们在做FineUI控件库,而且我们也做了超过 9 年的时间,在和浏览器无数次的交往中,也发现了多个浏览器自身的BUG,并公开出来方便大家查阅: 分享IE7一个神奇的BUG(不是封闭 ...
- centos7 Mysql备份还原并下载到windos
数据库备份 1.show databases; #查看一下数据库 2.对应数据库做备份开始: mysqldump -u root -p 需要备份的数据库 > db.sql #把它备份到 ...