题意: 给n(n<=10^6)个非负数字,放在一个数组num中,再给一个特殊值m。求将这个数组分成任意多个区间,每个区间[a,b]的值定义为( sigma(num[i] | (a<=i<=b)) ) ^ 2 + m.要区间值总和最小,并输出此最小值  (PS:这道题不用考虑暴int问题,当然这是AC以后才发现的)。

解题思路: 定义sum[i]=sigma(num[j] | (1<=j<=i)) (这里假设num数组下标从1开始)

     定义f(j,i) = (sum[i]-sum[j])^2+m (区间[j+1,i]的值)

     定义dp[i]为从1到i这段的题意要求的那个最小值,根据其定义就有dp[i]=min{ dp[j]+f(j,i) | 0<=j<i } (****)。(思考为什么这样定义?)

     另外定义一个仅作标识用的量dp[j,i],表示从j到i这段题意要求的最小区间值和,即dp[1,k]=dp[k]。

裸的枚举当然是不科学的,效率太低。与上一篇博客略有类似,计算dp[i]要用以前的结果,如何对要枚举的状态进行优化呢?

令(k<j<i) ,x>0;

  1. 若有dp[k]+f(k,i)> dp[j]+f(j,i),那么一定有dp[i+x] > dp[k]+f(k+1,x+i); 也就是说 k一定不是对应着i的一个可能最优解。 在求解dp[i+x]时,k点就不用枚举了。
  2. 若有dp[k]+f(k,i)<= dp[j]+f(j,i),那么一定有dp[i+x] > dp[j]+f(j,i+x)。

重新思考一下(****)中dp[i]的定义,应用数学归纳法:

dp[1]=f(0,1) 或者dp[1]=f(0,1)+dp[0] (dp[0]=0)

dp[2]=min{dp[1]+f(2,2),dp[0]+f(1,2)} (刚好对应两种区间拆分方式)

假设dp[k]用上式定义也正确,那么

  dp[k+1]=min{ dp[1,j]+dp[j+1,k+1] | (j <= k) },如果dp[j+1,k+1]==f(j,k+1),原式自然成立;

  那即使不成立呢? 也就是说存在一个j<jj<k, 使得dp[j+1,k+1]==f(j,jj)+dp[jj+1,k+1],所以

   dp[1,j]+f(j,jj)+dp[jj+1,k+1]描述的是什么呢?dp[1,j]+f(j,jj)正是dp[jj]的一个可能最优解。dp[k+1]=min{dp[jj]+dp[jj+1,k+1], dp[k+1] },原式成立!

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=;
int num[maxn],pl;
int sum[maxn];
int dp[maxn];
int que[maxn];
int f(int j,int i){
return (sum[i]-sum[j])*(sum[i]-sum[j])+pl;
}
int gety(int j,int k){
return dp[j]+sum[j]*sum[j]-dp[k]-sum[k]*sum[k];
}
int getx(int j,int k){
return (sum[j]-sum[k])<<;
}
int main()
{
int n;
while(scanf("%d%d",&n,&pl) != EOF){
for(int i=;i<=n;i++)
scanf("%d",&num[i]);
sum[]=dp[]=;
for(int i=;i<=n;i++)
sum[i]=sum[i-]+num[i];
int head=,tail=;
que[tail++]=;
for(int i=;i<=n;i++){
while(head+ < tail && gety(que[head+],que[head])<=getx(que[head+],que[head])*sum[i])
head++;
dp[i]=dp[que[head]]+f(que[head],i);
while((head+ < tail) && gety(i,que[tail-])*getx(que[tail-],que[tail-])<=gety(que[tail-],que[tail-])*getx(i,que[tail-]))
tail--;
que[tail++]=i;
}
printf("%d\n",dp[n]);
}
return ;
}

hdu3507的更多相关文章

  1. 【hdu3507】Print Article 【斜率优化dp】

    题意 https://cn.vjudge.net/problem/HDU-3507 分析 斜率优化的模板题 #include <cstdio> #include <cstring&g ...

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

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

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

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

  4. c++之路进阶——hdu3507(Print Article)

    参考博文:http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html//讲的真的很好,有个小错误,博客里的num全为sum,像我这种 ...

  5. HDU3507 print artical

    题目大意:有N个数字a[N],每输出连续的一串,它的费用是 “这行数字的平方加上一个常数M”.问如何输出使得总费用最小.(n<=500000) 分析:动态规划方程为:dp[i]=dp[j]+M+ ...

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

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

  7. 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 ...

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

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

  9. hdu3507 Print Article

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

随机推荐

  1. Linux mint 17中文输入法安装,改动linux mint与windows7双系统启动顺序

    安装好linux mint17后,进入mint系统,首先须要一个比較合适的中文输入法. 一.首先迎来的就是安装中文输入法了,之前听说搜狗为ubuntu kinly定制了输入法,所以就想安装搜狗输入法, ...

  2. html系列教程--center dl dt dd div

    <center> 标签:对其所包括的文本进行水平居中. <datalist> 标签:定义列表,与 input 元素配合使用该元素,来定义 input 可能的值 demo: &l ...

  3. IOS 获取手机各种信息

    /手机序列号      NSString* identifierNumber = [[UIDevice currentDevice] uniqueIdentifier];     NSLog(@&qu ...

  4. Phalcon 性能最高的php框架没有之一

    最近有个朋友说他们现在在用Phalcon框架开发项目,明显感觉性能有很大的提升,所有着手学习下这个高性能框架,网上是这样说的“虽然以C语言编写达到较高的效能,但相对的一项缺点就是在服务器上必须拥有管理 ...

  5. Java学习之finally关键字总结

    Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...

  6. Android DatePicker和TimePicker

    监测日期改变的监听器:      OnDateChangedListener和OnTimeChangedListener()           当用户改变Datepicker里的年.月.日时,将触发 ...

  7. Python进阶之匿名函数(关键词lambda)

    匿名函数 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB"," ...

  8. 软件测试学习日志———— round 2 Junit+intellj idea 安装及简单的测试使用

    今天是软件测试的上机,主要内容是对junit的安装以及对一个简单类的测试实践.老师推荐用eclipse,但是我原来一直在 用intellj Idea,所以我试了试intellj Idea对junit的 ...

  9. log实例

    配置详解见2014.10月篇 log4j的pom.xml <dependency> <groupId>log4j</groupId> <artifactId& ...

  10. 强制删除正在连接的Oracle用户,以删除SDE用户为例

    . 有时候想强制删除一个已经连接的Oracle用户,不能直接删除,可以用Kill会话信息. 比如今天想删除一个被连接的SDE用户,可以用以下方法删除一个“正在被连接”的用户. 1.查看所有用户的会话信 ...