题意: 给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. 佩特来项目经验小集合(2)___组合查询存储过程,报错 &quot;varchar JBID=&#39;&#39; 转换成数据类型 int 时失败&quot;

       今天写一个组合查询的存储过程遇到这样一个问题:在将 varchar 值 'SELECT * FROM View_DLS_WXJD_Customer WHERE 1=1 and JBID ='' ...

  2. struts2整合json要注意的问题

    昨天struts2整合json,一直出错: There is no Action mapped for namespace / and action name ... HTTP Status 404 ...

  3. UINavigationController技巧<一>——修改返回按钮的标题

    UINavigationController 一般push到另一界面后,返回按钮标题便是上一页面的title,但是对于push的第一页或者是上一页面没有title的,返回按钮标题便是默认back,如图 ...

  4. Java压缩技术的学习

    由于工作的需要,经常要手动去打上线安装包,为了方便,自己写程序去帮助打包.使用过Unix或者Linux的人都基本上都用过tar打包以及gzip压缩,但在Windows下使用得最多的压缩还是RAR和Zi ...

  5. javascript动态改变iframe的src

    页面中需要动态的改变iframe的地址,方法有: 1. window.frames["chartFrame"].document.location = "<%=ba ...

  6. iOS 混合网页开发 问题

    在利用JavaScriptCore与H5交互时出现异常提示: This application is modifying the autolayout engine from a background ...

  7. JSON、XML 解析

    iOS开发--XML/JSON数据解析 不错的文章http://www.jianshu.com/p/a54d367adb2a

  8. IE下的bug

    断断续续的在开发过程中收集了好多的bug以及其解决的办法,都在这个文章里面记录下来了!希望以后解决类似问题的时候能够快速解决 ,也希望大家能在留言里面跟进自己发现的ie6 7 8bug和解决办法! 1 ...

  9. Java程序执行Linux命令

    Java程序中要执行linux命令主要依赖2个类:Process和Runtime 首先看一下Process类: ProcessBuilder.start() 和 Runtime.exec 方法创建一个 ...

  10. OC语法3——点语法,self关键字

    点语法:   为了给程序员提供便捷,OC中也引入了点语法.不过它和Java中点语法的意义是完全不同的. 在Java中无论调用任何方法,还是访问public类型的成员变量都是用点语法(.号). 而在OC ...