博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3648 [APIO2014]序列分割(斜率优化)
阅读量:6087 次
发布时间:2019-06-20

本文共 2165 字,大约阅读时间需要 7 分钟。

 

没想到这种多个状态转移的还能用上斜率优化……学到了……

首先我们可以发现,切的顺序对最终答案是没有影响的

比方说有一个序列$abc$,每一个字母都代表几个数字,那么先切$ab$再切$bc$,得分是$ab+bc+ac$,而如果先切$bc$再切$ab$,得分也是$ab+bc+ac$,不难看出得分是一样的

那么我们可以考虑一下转移方程$$dp[a][i]=max\{dp[a-1][j]+sum[j]*(sum[i]-sum[j])\}$$

其中$a$表示切几刀,$sum$表示前缀和

然后发现空间复杂度太大了,又发现每一刀的状态只与前一刀有关,那么可以用滚动数组优化

然后上面的转移是$O(n^2k)$的,那么考虑用斜率优化优化到$O(nk)$(以下省略dp的第一维)

我们假设$j>k$且$j$比$k$更优,则有$$dp[j]+sum[j]*(sum[i]-sum[j])>dp[k]+sum[k]*(sum[i]-sum[k])$$

$$(dp[j]-sum[j]^2)-(dp[k]-sum[k]^2)>sum[i]*sum[k]-sum[i]*sum[j]$$

因为$sum[k]-sum[j]$是负数,所以除的时候不等式要变号

$$\frac{(dp[j]-sum[j]^2)-(dp[k]-sum[k]^2)}{sum[k]-sum[j]}<sum[i]$$

然后直接上斜率优化

注意特判$sum[k]-sum[j]=0$,随便返回极大值或极小值

顺便注意记录路径

1 //minamoto 2 #include
3 #include
4 #define ll long long 5 using namespace std; 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 7 char buf[1<<21],*p1=buf,*p2=buf; 8 inline int read(){ 9 #define num ch-'0'10 char ch;bool flag=0;int res;11 while(!isdigit(ch=getc()))12 (ch=='-')&&(flag=true);13 for(res=num;isdigit(ch=getc());res=res*10+num);14 (flag)&&(res=-res);15 #undef num16 return res;17 }18 char sr[1<<21],z[20];int C=-1,Z;19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}20 inline void print(int x){21 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;22 while(z[++Z]=x%10+48,x/=10);23 while(sr[++C]=z[Z],--Z);sr[++C]=' ';24 }25 const int N=100005;26 int to[205][N],q[N],n,k,h,t,r;27 ll sum[N],dp[2][N];28 inline double slope(int j,int k){29 if(sum[j]==sum[k]) return 1e18;30 return ((dp[r^1][j]-sum[j]*sum[j])-(dp[r^1][k]-sum[k]*sum[k]))*1.0/(sum[k]-sum[j]);31 }32 int main(){33 //freopen("testdata.in","r",stdin);34 n=read(),k=read();35 for(int i=1;i<=n;++i) sum[i]=read()+sum[i-1];36 for(int a=1;a<=k;++a){37 r=a&1;38 h=t=0;39 for(int i=1;i<=n;++i){40 while(h
slope(q[t-1],i)) --t;q[++t]=i;44 }45 }46 printf("%lld\n",dp[k&1][n]);47 for(int i=k,u=n;i;--i){48 u=to[i][u];49 print(u);50 }51 Ot();52 return 0;53 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9546240.html

你可能感兴趣的文章
数据结构与算法:二分查找
查看>>
使用思科模拟器Packet Tracer与GNS3配置IPv6隧道
查看>>
Linux设备驱动之Ioctl控制【转】
查看>>
iOS开发-NSPredicate
查看>>
《Clojure编程乐趣》—— 第1章,第1.2节为何(又一种)Lisp
查看>>
如何快速部署Node.js项目
查看>>
《移动App测试的22条军规》—App测试综合案例分析23.3节测试微信App的多任务和意外情况处理...
查看>>
《贝叶斯思维:统计建模的Python学习法》一1.6 M&M豆问题
查看>>
从代码层读懂HashMap的实现原理
查看>>
趋势在此汇集!2016杭州・云栖大会技术大咖专访系列合集
查看>>
Android应用框架之PackageManagerService
查看>>
Myexclipse创建Junit测试
查看>>
【Spark Summit East 2017】EasyMapReduce:利用Spark与Docker以MapReduce方式赋能大规模科学工具...
查看>>
【Spark Summit East 2017】工程快速索引
查看>>
使用struts中的DisPatchAction的时候需要用到的jar包
查看>>
HTML/JS 调用android方法,开发 Android。
查看>>
redis 简介
查看>>
Apple Pay来抢滩了!求所有被鄙视群体的心理阴影面积
查看>>
NASA计划被说口出狂言?阿里用开源证明技术实力
查看>>
go 语言 优势及 主要用途
查看>>