Print Article

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 11761    Accepted Submission(s): 3586

Problem Description
Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it to print articles. But it is too old to work for a long time and it will certainly wear and tear, so Zero use a cost to evaluate this degree.
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.
 
Input
There are many test cases. For each test case, There are two numbers N and M in the first line (0 ≤ n ≤ 500000, 0 ≤ M ≤ 1000). Then, there are N numbers in the next 2 to N + 1 lines. Input are terminated by EOF.
 
Output
A single number, meaning the mininum cost to print the article.
 
Sample Input
5 5
5
9
5
7
5
 
Sample Output
230
 
Author
Xnozero
 
Source
 
Recommend
zhengfeng   |   We have carefully selected several similar problems for you:  3506 3501 3504 3505 3498 

大概题意就是要输出N个数字a[N],输出的时候可以连续连续的输出,每连续输出一串,它的费用是 “这串数字和的平方加上一个常数M”。

我们设dp[i]表示输出到i的时候最少的花费,sum[i]表示从a[1]到a[i]的数字和。于是方程就是:

dp[i]=dp[j]+M+(sum[i]-sum[j])^2;

很显然这个是一个二维的。题目的数字有500000个,不用试了,二维铁定超时了。那我们就来试试斜率优化吧,看看是如何做到从O(n^2)复杂度降到O(n)的。

分析:

我们假设k<j<i。如果在j的时候决策要比在k的时候决策好,那么也是就是dp[j]+M+(sum[i]-sum[j])^2<dp[k]+M+(sum[i]-sum[k])^2。(因为是最小花费嘛,所以优就是小于)

两边移项一下,得到:(dp[j]+num[j]^2-(dp[k]+num[k]^2))/(2*(num[j]-num[k]))<sum[i]。我们把dp[j]-num[j]^2看做是yj,把2*num[j]看成是xj。

那么不就是yj-yk/xj-xk<sum[i]么?   左边是不是斜率的表示?

那么yj-yk/xj-xk<sum[i]说明了什么呢?  我们前面是不是假设j的决策比k的决策要好才得到这个表示的? 如果是的话,那么就说明g[j,k]=yj-jk/xj-xk<sum[i]代表这j的决策比k的决策要更优。

关键的来了:现在从左到右,还是设k<j<i,如果g[i,j]<g[j,k],那么j点便永远不可能成为最优解,可以直接将它踢出我们的最优解集。为什么呢?

我们假设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点。

排除多余的点,这便是一种优化!

接下来看看如何找最优解。

设k<j<i。

由于我们排除了g[i,j]<g[j,k]的情况,所以整个有效点集呈现一种上凸性质,即k j的斜率要大于j i的斜率。

这样,从左到右,斜率之间就是单调递减的了。当我们的最优解取得在j点的时候,那么k点不可能再取得比j点更优的解了,于是k点也可以排除。换句话说,j点之前的点全部不可能再比j点更优了,可以全部从解集中排除。

于是对于这题我们对于斜率优化做法可以总结如下:

1,用一个单调队列来维护解集。

2,假设队列中从头到尾已经有元素a b c。那么当d要入队的时候,我们维护队列的上凸性质,即如果g[d,c]<g[c,b],那么就将c点删除。直到找到g[d,x]>=g[x,y]为止,并将d点加入在该位置中。

3,求解时候,从队头开始,如果已有元素a b c,当i点要求解时,如果g[b,a]<sum[i],那么说明b点比a点更优,a点可以排除,于是a出队。最后dp[i]=getDp(q[head])。

#include<cstdio>
#define pf(x) ((x)*(x))
using namespace std;
const int N=5e5+;
int n,sum[N],q[N];
int m,f[N];
inline int gety(int j,int k){
return f[j]+pf(sum[j])-(f[k]+pf(sum[k]));
}
inline int getx(int j,int k){
return sum[j]-sum[k]<<;
}
int main(){
while(~scanf("%d%d",&n,&m)){
for(int i=;i<=n;i++) scanf("%d",sum+i),sum[i]+=sum[i-];
int h=,t=;q[t]=;
for(int i=;i<=n;i++){
for(;h<t&&gety(q[h+],q[h])<=sum[i]*getx(q[h+],q[h]);h++);
f[i]=f[q[h]]+pf(sum[i]-sum[q[h]])+m;
for(;h<t&&gety(i,q[t])*getx(q[t],q[t-])<=gety(q[t],q[t-])*getx(i,q[t]);t--);
q[++t]=i;
}
printf("%d\n",f[n]);
}
return ;
}

hdu3507 Print Article[斜率优化dp入门题]的更多相关文章

  1. [hdu3507 Print Article]斜率优化dp入门

    题意:需要打印n个正整数,1个数要么单独打印要么和前面一个数一起打印,1次打印1组数的代价为这组数的和的平方加上常数M.求最小代价. 思路:如果令dp[i]为打印前i个数的最小代价,那么有 dp[i] ...

  2. HDU3507 Print Article —— 斜率优化DP

    题目链接:https://vjudge.net/problem/HDU-3507 Print Article Time Limit: 9000/3000 MS (Java/Others)    Mem ...

  3. HDU3507 Print Article(斜率优化dp)

    前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...

  4. HDU3507 Print Article (斜率优化DP基础复习)

    pid=3507">传送门 大意:打印一篇文章,连续打印一堆字的花费是这一堆的和的平方加上一个常数M. 首先我们写出状态转移方程 :f[i]=f[j]+(sum[i]−sum[j])2 ...

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

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

  6. Print Article /// 斜率优化DP oj26302

    题目大意: 经典题 数学分析 G(a,b)<sum[i]时 a优于b G(a,b)<G(b,c)<sum[i]时 b必不为最优 #include <bits/stdc++.h& ...

  7. hdu 3507 Print Article —— 斜率优化DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3507 设 f[i],则 f[i] = f[j] + (s[i]-s[j])*(s[i]-s[j]) + m ...

  8. hdu3507 Print Article(斜率DP优化)

    Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it ...

  9. hdu3507(初识斜率优化DP)

    hdu3507 题意 给出 N 个数字,输出的时候可以选择连续的输出,每连续输出一串,它的费用是 这串数字和的平方加上一个常数 M. 分析 斜率优化dp,入门题. 参考 参考 得到 dp 方程后,发现 ...

随机推荐

  1. unity3d 资源打包加密 整理

    资源打包脚本,放到Assets\Editor 文件夹下 using UnityEngine; using System.Collections; using UnityEditor; using Sy ...

  2. Libertarian

    Libertarians as the real god-son has the consistent faith of humanity freedom. The super libertarian ...

  3. 【数据分析知识点】detailed table of contents

    Exploratory Data Analysis - Detailed Table of Contents http://www.itl.nist.gov/div898/handbook/eda/e ...

  4. 基于maven使用IDEA创建多模块项目

    原文地址:http://blog.csdn.net/williamhappy/article/details/54376855 鉴于最近学习一个分布式项目的开发,讲一下关于使用IntelliJ IDE ...

  5. todo:区块链????????

    2018年这个春节,人人都在讲btc.ico.区块链. 恶补了几天区块链的知识和文章,一总结就是:一头雾水,没有哪个vc.创业者.技术人员 讲明白区块链到底是什么,技术上如何实现,就是哪些研读过中本聪 ...

  6. ubuntu-12.04.5-desktop-i386.iso:ubuntu-12.04.5-desktop-i386:安装Oracle11gR2

    ubuntu 桌面版的安装不介绍. 如何安装oracle:核心步骤和关键点. ln -sf /bin/bash /bin/sh ln -sf /usr/bin/basename /bin/basena ...

  7. android EditText设置弹出数字输入法键盘

    <EditText      android:id="@+id/edit_digit_input"      android:layout_width="wrap_ ...

  8. IFrame实现页面无刷新

    一.html 和s代码段 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...

  9. pycharm使用docker镜像的python解释器,pycahrm可视化操作和管理dcoker

    网上关于pycahrm怎么使用docker容器的python解释器的科普,这方面太少,一半都只介绍pycahrm怎么使用linux的解释器.首先pycahrm确保是pro版本. 下面详细的介绍步骤 首 ...

  10. linux alias使用

    安装一些软件 python redis mysql jdk,都需要添加环境变量,一个路径添加到了环境变量,就可以直接在linux控制台输入  xx命令. 否则不添加环境变量,使用xx就会提示找不到命令 ...