• 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
    ",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

  • 相关阅读:
    用jQuery写的一个简单的弹出窗口(IE7\IE8\FF3)
    live write test
    sql2
    查询所有表索引
    java初学问题记录(2012.02.092012.02.16)
    SQL
    centso7网卡bond
    vmware模板
    Dockerfile参考
    Docker简单介绍
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11366957.html
Copyright © 2020-2023  润新知