斜率优化dp练习
1.HDU3507
裸题,有助于理解斜率优化的精髓。
dp[i]=min(dp[j]+m+(sum[i]-sum[j])2)
很显然不是单调队列。
根据斜率优化的的定义,就是先设两个决策j,k
什么时候我们认为在 i 的环境下 j 比 k 好呢?根据上面的递推式,得到下面这么一个式子
dp[j]+m+(sum[i]-sum[j])2<dp[k]+m+(sum[i]-sum[k])2
打开括号:
dp[j]+m+sum[i]2+sum[j]2-2*sum[i]*sum[j]<dp[k]+m+sum[i]2+sum[k]2-2*sum[i]*sum[k]
移项,将有 i 的项移到右侧:
dp[j]+sum[j]2-dp[k]-sum[k]2<2*sum[i]*(sum[j]-sum[k])
除下来:
(dp[j]+sum[j]2-dp[k]-sum[k]2)/[2*(sum[j]-sum[k])]<sum[i]
好了这就是斜率了^_^
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
int Q[];
lnt sum[];
lnt dp[];
int h,t;
lnt n;
lnt m;
lnt X(int x)
{
return dp[x]+sum[x]*sum[x];
}
lnt tp(int i,int j)
{
return X(i)-X(j);
}
lnt btm(int i,int j)
{
return *sum[i]-*sum[j];
}
int main()
{
while(scanf("%lld%lld",&n,&m)!=EOF)
{
sum[]=;
for(int i=;i<=n;i++)
scanf("%lld",&sum[i]);
for(int i=;i<=n;i++)
sum[i]+=sum[i-];
h=t=;
Q[]=;
dp[]=;
for(int i=;i<=n;i++)
{
while(h<t&&(tp(Q[h+],Q[h])<=sum[i]*btm(Q[h+],Q[h])))
h++;
dp[i]=dp[Q[h]]+m+(sum[i]-sum[Q[h]])*(sum[i]-sum[Q[h]]);
while(h<t&&(tp(Q[t],Q[t-])*btm(i,Q[t])>=tp(i,Q[t])*btm(Q[t],Q[t-])))
t--;
Q[++t]=i;
}
printf("%lld\n",dp[n]);
}
return ;
}
这道题依然斜率单调
dp方程自己推:
dp[i]=min(dp[j]+(i-j-1+sum[i]-sum[j]-L)2)
依然假设在 i 的环境下决策 j 优于 k
那么:
dp[j]+(i-j-1+sum[i]-sum[j]-L)2<dp[k]+(i-k-1+sum[i]-sum[k]-L)2
将常数项与与 i 有关的项放到一起,展开:
(sum[j]+j)2-2*(i+sum[i]-L-1)*(sum[j]+j)+dp[j]<(sum[k]+k)2-2*(i+sum[i]-L-1)*(sum[k]+k)+dp[k]
设函数 f(x)=sum[x]+x , h(x)=x+sum[x]-L-1 , g(x)=dp[x]+f(x)2
得到当:
g(j)-g(k)<2*h(i)*(f(j)-f(k)) 时,j 比 k 优秀。
f(x)单调递增,斜率单调。
时间复杂度O(n)
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
lnt sum[];
lnt dp[];
int Q[];
int h,t;
int n;
lnt L;
lnt f(int x)
{
return (sum[x]+(lnt)(x));
}
lnt k(int x)
{
return ((lnt)(x)+sum[x]-L-);
}
lnt g(int x)
{
return (dp[x]+f(x)*f(x));
}
lnt squ(lnt x)
{
return x*x;
}
int main()
{
scanf("%d%lld",&n,&L);
for(int i=;i<=n;i++)
{
scanf("%lld",&sum[i]);
sum[i]+=sum[i-];
}
Q[]=;
dp[]=;
h=t=;
for(int i=;i<=n;i++)
{
while(h<t&&g(Q[h+])-g(Q[h])<2ll*k(i)*(f(Q[h+])-f(Q[h])))
h++;
dp[i]=dp[Q[h]]+squ((lnt)(i-Q[h]-)+sum[i]-sum[Q[h]]-L);
while(h<t&&(((g(Q[t-])-g(Q[t]))*(f(Q[t])-f(i)))>((g(Q[t])-g(i))*(f(Q[t-])-f(Q[t])))))
t--;
Q[++t]=i;
}
printf("%lld\n",dp[n]);
return ;
}
斜率单调。
方程自己推:
设:g(x)=a*x2+b*x+c
dp[i]=max(dp[j]+g(sum[i]-sum[j]))
设在 i 环境下决策 j 优于 k
dp[j]+g(sum[i]-sum[j])>dp[k]+g(sum[i]-sum[k])
设f(x)=dp[x]+a*sum[x]2-b*sum[x]
则当:
f(j)-f(k)>2*a*sum[i]*(sum[j]-sum[k])
设 j > k 斜率单调
时间复杂度O(n)
代码:
#include<cstdio>
#include<cstring>
#include<cstdio>
typedef long long lnt;
lnt sum[];
lnt dp[];
int Q[];
int h,t;
int n;
lnt a,b,c;
lnt f(int x)
{
return dp[x]+a*sum[x]*sum[x]-b*sum[x];
}
lnt g(lnt x)
{
return a*x*x+b*x+c;
}
int main(void)
{
sum[]=;
h=t=;
scanf("%d",&n);
scanf("%lld%lld%lld",&a,&b,&c);
for(int i=;i<=n;i++)
{
scanf("%lld",&sum[i]);
sum[i]+=sum[i-];
}
Q[]=;
dp[]=;
for(int i=;i<=n;i++)
{
while(h<t&&(f(Q[h+])-f(Q[h]))>*a*sum[i]*(sum[Q[h+]]-sum[Q[h]]))
h++;
dp[i]=dp[Q[h]]+g(sum[i]-sum[Q[h]]);
while(h<t&&(f(Q[t])-f(Q[t-]))*(sum[i]-sum[Q[t]])<=(f(i)-f(Q[t]))*(sum[Q[t]]-sum[Q[t-]]))
t--;
Q[++t]=i;
}
printf("%lld\n",dp[n]);
return ;
}
这次变成二维的了。
都一样,展开方程+斜率优化。
这次要对于每一天进行O(n)转移,共m天,时间复杂度O(n*m)
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
lnt dp[][];
lnt sum[];
int Q[];
lnt n,m;
lnt L;
int h,t;
lnt squ(lnt x)
{
return x*x;
}
lnt f(int x,int i)
{
return dp[x][i]+m*squ(sum[x])+2ll*L*sum[x];
}
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%lld",&sum[i]);
sum[i]+=sum[i-];
}
L=sum[n];
for(int i=;i<=n;i++)
{
dp[i][]=m*squ(sum[i])-2ll*L*sum[i];
}
for(int d=;d<=m;d++)
{
t=h=;
Q[]=;
for(int i=;i<=n;i++)
{
while(h<t&&(f(Q[h+],d-)-f(Q[h],d-))<2ll*m*sum[i]*(sum[Q[h+]]-sum[Q[h]]))
h++;
dp[i][d]=dp[Q[h]][d-]+m*squ(sum[i]-sum[Q[h]])-2ll*L*(sum[i]-sum[Q[h]]);
while(h<t&&(f(Q[t],d-)-f(Q[t-],d-))*(sum[i]-sum[Q[t]])>(f(i,d-)-f(Q[t],d-))*(sum[Q[t]]-sum[Q[t-]]))
t--;
Q[++t]=i;
}
}
printf("%lld\n",dp[n][m]+squ(L));
return ;
}
斜率优化dp练习的更多相关文章
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- BZOJ 3156: 防御准备 斜率优化DP
3156: 防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...
- HDU2829 Lawrence(斜率优化dp)
学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...
- HDU3507 Print Article(斜率优化dp)
前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...
- HDU 3507 Print Article(斜率优化DP)
题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...
- 斜率优化dp(POJ1180 Uva1451)
学这个斜率优化dp却找到这个真心容易出错的题目,其中要从n倒过来到1的确实没有想到,另外斜率优化dp的算法一开始看网上各种大牛博客自以为懂了,最后才发现是错了. 不过觉得看那些博客中都是用文字来描述, ...
随机推荐
- Android 4.3 系统裁剪——删除不使用的app及添加自己app
删除不使用的apk 系统自带的app位置是在/android4.3/packages/apps 以下是一些APP作用分析: | |– BasicSmsReceiver | |– Bluetooth ( ...
- Spring MVC数据转换
样例:把一个字符串封装而一个对象. 如:username:password格式的数据ZhangSan:1234.我们把这个数据封装成一个User对象.以下分别使用属性编辑器与转换器来实现. 1.自己定 ...
- hdu1280 前m大的数(数组下标排序)
前m大的数 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- phpMyAdmin出现找不到mysql扩展和Cannot log in to the MySQL server问题
环境:Centos6.5,Apache2.4, PHP5.5, MySql5.6. phpMyAdmin版本:https://files.phpmyadmin.net/phpMyAdmin/4.4.1 ...
- HUE配置文件hue.ini 的filebrowser模块详解(图文详解)(分HA集群和非HA集群)
不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...
- 实现人脸识别性别之路---open CV将图片显示出来
import cv2filename='E:\\tensorflow\\bu.jpg'#图片的地址 # face_cascade=cv2.CascadeClassifier('C:\\anconda3 ...
- 【Uva 10817】Headmaster's Headache
[Link]: [Description] 一个学校,有s门课程(1<=s <=8),里面本身已经有m个老师了,然后还想招聘n个老师: 给出这m个老师和n个来应聘的老师的信息; (c[i] ...
- 洛谷—— P1328 生活大爆炸版石头剪刀布
https://www.luogu.org/problem/show?pid=1328 题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负.在< ...
- 洛谷 P2690 接苹果
P2690 接苹果 题目背景 USACO 题目描述 很少有人知道奶牛爱吃苹果.农夫约翰的农场上有两棵苹果树(编号为1和2), 每一棵树上都长满了苹果.奶牛贝茜无法摘下树上的苹果,所以她只能等待苹果 从 ...
- C# 操作Excel常见错误
1.未在本地注册 string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FilePath + &qu ...