斜率优化DP习题集粹——从入门到放弃
来源:互联网 发布:php旅游系统 编辑:程序博客网 时间:2024/06/17 14:55
前言
斜率优化,在某种程度上说,可以看作是一种使决策具有单调性,从而降低时间复杂度的一种手段,但好像不是很easy的样子。
啊,学渣苦,学渣累。——Friedrich Taylor
决策单调性
要讲斜率优化怎么能不讲决策单调性
决策单调性是一种性质(废话),利用这一性质我们可以以更优的时间复杂度来解题
斜率优化
那么斜率优化是干什么的呢?
可以看做是斜率优化欲图维护一个凸包
在凸包上的决策具有单调性
习题
著名习题(1):玩具装箱
只要是讲单调性好像都会把这道题
不讲解
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;inline long long read(){long long i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(long long x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}#define stan 55555long long f[stan],que[stan],length[stan],pre[stan],n,boldl;double slope(int x,int y){return (f[x]-f[y]+length[x]*length[x]-length[y]*length[y])*0.5/(length[x]-length[y]);}signed main(){n=read();boldl=read()+1;for(int i=1;i<=n;++i){length[i]=read();length[i]+=length[i-1]+1;pre[i]=length[i]-boldl;}int l=1,r=1;que[1]=0;for(int i=1;i<=n;++i){while(l<r&&slope(que[l],que[l+1])<=pre[i]) ++l;f[i]=f[que[l]]+(pre[i]-length[que[l]])*(pre[i]-length[que[l]]);while(l<r&&slope(que[r],i)<slope(que[r-1],que[r])) --r;que[++r]=i;}write(f[n]);return 0;}
著名习题(2):特别行动队
不解释
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define int long longusing namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}#define stan 1111111int n,a,b,c,x,sum[stan],f[stan],l,r,que[stan];double slope(int k,int j){return double(f[k]-f[j]+a*(sum[k]-sum[j])*(sum[k]+sum[j])-b*(sum[k]-sum[j]))/double(2*a*(sum[k]-sum[j]));}signed main(){n=read();a=read();b=read();c=read();for(int i=1;i<=n;++i){x=read();sum[i]=sum[i-1]+x;}for(int i=1;i<=n;++i){while(l<r&&slope(que[l],que[l+1])<sum[i]) ++l;int k=que[l];f[i]=f[k]+a*(sum[i]-sum[k])*(sum[i]-sum[k])+b*(sum[i]-sum[k])+c;while(l<r&&slope(que[r-1],que[r])>slope(que[r],i)) --r;que[++r]=i;}write(f[n]);return 0;}
非著名习题:序列分割(BZOJ3675)
可以发现:你最后的结果和你分割的次第并没有什么关系
所以依次枚举并没有问题
至于指定次数,可以枚举k次
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define int long longusing namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];void write(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}#define stan 111111#define sten 222int f[stan][2],sum[stan],n,k,pos,l,r,que[stan];inline int lef(const int a,const int b,const int c){return f[a][c]-f[b][c]+sum[b]*sum[b]-sum[a]*sum[a];}inline int righ(const int a,const int b){return sum[b]-sum[a];}signed main(){n=read();k=read();for(int i=1;i<=n;++i)sum[i]=read()+sum[i-1];for(int j=1;j<=k;++j){l=0,r=0,que[l]=0;pos=j&1;for(int i=1;i<=n;++i){while(l<r&&lef(que[l],que[l+1],pos^1)<=righ(que[l],que[l+1])*sum[i]) ++l;int t=que[l];f[i][pos]=f[t][pos^1]+sum[t]*(sum[i]-sum[t]);while(l<r&&lef(que[r-1],que[r],pos^1)*righ(que[r],i)>=lef(que[r],i,pos^1)*righ(que[r-1],que[r])) --r;que[++r]=i;}}write(f[n][pos]); return 0;}
阅读全文
0 0
- 斜率优化DP习题集粹——从入门到放弃
- kotlin——从入门到放弃
- hdu3507 斜率优化dp入门
- 【模板&2个套路】数位DP 从入门到放弃
- FPGA视觉从入门到放弃——Canny算子
- Git从入门到放弃——Git命令篇
- 徐宜生系列——[推送,从入门到放弃]
- 弹弹堂——从入门到放弃
- Java从入门到放弃——选择排序
- 无旋Treap——从入门到放弃
- 简单动态规划(1)——从入门到放弃
- 简单动态规划(2)——从入门到放弃
- 简单动态规划(3)——从入门到放弃
- 简单动态规划(4)——从入门到放弃
- Kotlin从入门到放弃(三)——协程
- UnityShader从入门到放弃(五)漫反射—逐片元光照
- Freemarker 从入门到放弃
- kmp从入门到放弃
- 【安全牛学习笔记】POP3
- 朴素贝叶斯分类器实现成绩等级预测
- rabbitmq rabbitmq.config详细配置参数
- ArrayList和LinkedList性能分析
- android studio关联源码(choose sources)
- 斜率优化DP习题集粹——从入门到放弃
- 了解switch的选择器的特点并用switch计算指定的年月日是本年的第几天
- 安卓mediaformat api详解
- Linux 文件系统与设备文件系统(3)
- redis主从配置及主从切换
- Hadoop RPC机制的使用
- uml图的成员
- Python+django实现邮箱验证登录
- CSS精灵技术及其优化经验分享