zoukankan      html  css  js  c++  java
  • BZOJ.3675.[APIO2014]序列分割(DP 斜率优化)

    BZOJ
    洛谷
    UOJ

    似乎切割顺序很麻烦。但是写一下不同切割顺序的值发现,答案是一样的。所以实际和切割顺序无关,只与切在哪有关。

    (f[i][k])表示这次在(i)处切,一共已经切了(k)次的最大价值。注意不要算上其它块的价值。
    那么(f[i][k]=min{f[j][k-1]+s_j*(s_i-s_j)})
    (f[j][k-1])就是上一次DP得到的(f)数组。把(k)放在第一层循环,就可以斜率优化了。
    复杂度(O(nk))
    当然可以带权二分优化到(O(nlog k))

    为啥并没有感觉到有卡常的意思...
    UOJ是原数据吧QAQ,卡精度(其实不等号加个等号就好了)还卡常数(其实加个fread就过了)。

    横坐标还是取正数吧...

    //4436kb	20008ms
    #include <cstdio>
    #include <cctype>
    #include<cstring>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 500000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    //#define Sqr(x) (1ll*x*x)
    #define X(i,j) (s[i]-s[j])//delta_x
    #define Y(i,j) (f[i]-f[j]-sqr[i]+sqr[j])
    //#define Slope(i,j) (!X(i,j)?0:1.0*Y(i,j)/X(i,j))
    typedef long long LL;
    const int N=1e5+5;
    
    int s[N],q[N],id[N][202];
    LL f[N],g[N],sqr[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline double Slope(int i,int j)
    {
    	return !X(i,j)?1e15:1.0*Y(i,j)/X(i,j);
    }
    //void Print(int x,int k)
    //{
    //	if(!x) return;
    //	Print(id[x][k],k-1);
    //	printf("%d ",x);
    //}
    
    int main()
    {
    	static int Ans[202];
    	int n=read(),m=read();
    	for(int i=1; i<=n; ++i) s[i]=s[i-1]+read(),sqr[i]=1ll*s[i]*s[i];
    	for(int k=1; k<=m; ++k)
    	{
    		int h=1,t=1;
    		for(int i=k; i<=n; ++i)
    		{
    			while(h<t && Slope(q[h+1],q[h])>=-s[i]) ++h;//>= not >!
    			g[i]=f[q[h]]+1ll*s[q[h]]*(s[i]-s[q[h]]), id[i][k]=q[h];
    			while(h<t && Slope(q[t],q[t-1])<=Slope(i,q[t])) --t;
    			q[++t]=i;
    		}
    //		for(int i=k; i<=n; ++i) f[i]=g[i];
    		memcpy(f,g,n+1<<3);
    	}
    	printf("%lld
    ",f[n]);
    //	Print(id[n][m],m-1);
    	int t=0,x=id[n][m];
    	while(x) Ans[++t]=x, x=id[x][--m];
    	while(t) printf("%d ",Ans[t--]);
    
    	return 0;
    }
    
  • 相关阅读:
    python常见异常
    python+selenium动态抓取网页数据
    python基于scrapy配置日志
    Python依赖
    nginx配置详解
    Centos 用户登录失败N次后锁定用户禁止登陆
    CENTOS 7 firewalld详解,添加删除策略
    Centos7搭建Zookeeper 3.4.14集群
    Centos7安装FastDFS整合nginx
    VMware VCSA 6.7配置vSAN存储
  • 原文地址:https://www.cnblogs.com/SovietPower/p/10082034.html
Copyright © 2011-2022 走看看