P3648 [APIO2014]序列分割 斜率优化

Posted jackpei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3648 [APIO2014]序列分割 斜率优化相关的知识,希望对你有一定的参考价值。

题解:斜率优化\(DP\)

提交:\(2\)次(特意没开\(long\ long\),然后就死了)

题解:

好的先把自己的式子推了出来:
朴素:
定义\(f[i][j]\)表示前\(i\)个数进行\(j\)次切割的最大得分,\(s[i]\)为前缀和
那么转移方程为:
\(f[i][j]=\max(f[i-1][j]+s[j]*(s[i]-s[j]))\)
优化一下(省掉第一维):
\(f[i]=\max(mem[j]+s[j]*(s[i]-s[j])\),\(f[j])\),\(mem[j]\)相当于\(f[i-1][j]\)
换成斜率优化的式子:
\(mem[j]-s[j]^2=-s[i]*s[j]+f[i]\)
\(f[i]\)最大值,所以维护上凸包;斜率\(-s[i]\)单调递减,所以一个单调队列维护凸包。
然后康了一眼别人的题解:维护下凸包?
???黑人问号.jpg
后来发现自己就是个傻子:自己的是对的,只不过斜率那里和他们的相比少乘了个\(-1\)
\(ou\)。。那就没事了
(所以我写的还是自己的)

#include<cstdio>
#include<iostream>
#include<cstring>
#define R register int
#define ll long long
using namespace std;
namespace Luitaryi 
template<class I> inline I g(I& x)  x=0;
    register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
 const int N=100010;
int n,k,h,t,q[N],pre[210][N]; 
ll f[N],mem[N],s[N];
inline int X(int i) return s[i];
inline ll Y(int i) return mem[i]-s[i]*s[i];
inline double K(int i,int j) return 1.0*(Y(i)-Y(j))/(X(i)==X(j)?-1e-12:X(i)-X(j));
inline void main() 
    g(n),g(k); for(R i=1,x;i<=n;++i) g(x),s[i]=s[i-1]+x;
    for(R i=1;i<=k;++i)  h=t=0; 
        for(R j=1;j<=n;++j) 
            while(h<t&&K(q[h],q[h+1])>=-s[j]) ++h;
            f[j]=mem[q[h]]+1ll*s[q[h]]*s[j]-1ll*s[q[h]]*s[q[h]];
            pre[i][j]=q[h];
            while(h<t&&K(q[t-1],j)<=K(q[t],j)) --t; q[++t]=j;
         memcpy(mem,f,sizeof(f));
     printf("%lld\n",f[n]);
    for(R i=k,j=n;i;--i) j=pre[i][j],printf("%d ",j); puts("");

 signed main() Luitaryi::main(); return 0;

2019.08.17
83

以上是关于P3648 [APIO2014]序列分割 斜率优化的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3675[Apio2014]序列分割 斜率优化dp

动态规划(斜率优化):BZOJ 3675 [Apio2014]序列分割

[APIO2014]序列分割 --- 斜率优化DP

BZOJ3675APIO2014序列分割 [斜率优化DP]

bzoj3675[Apio2014]序列分割 斜率优化dp

[APIO2014]序列分割