• bzoj3675: [Apio2014]序列分割


    斜率优化。假如我讲不清楚就去%星感大神的题解

    我一开始想了个O(kn^3)的

    就是枚举k和n,然后枚举前面的点,然后枚举前面的点到当前点在哪断最优。

    而O(kn^2)咋搞呢

    我通过画图发现(其实是某人告诉了我分配律的问题)

    样例最后断出来是这样的

    (4),(1,3),(4,0),(2,3)

    然后答案其实就是每一个数和其他不同组的数乘一次

    DP方程就得出是这样的:f[i][now]=f[j][now^1]+s[j]*(s[i]-s[j]);

    其中now是滚动数组滚动枚举k的t

    然后斜率优化。

    但是有一个狗比问题,就是s[j1]==s[j2],这时除数为0要特判

    星感大神说他调样例的时候发现的。

    然而我的就玄学过了样例。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    LL a[110000],s[110000],f[110000][2];
    
    int now;
    double Y(int j){return double(f[j][now^1]-s[j]*s[j]);}
    double X(int j){return double(s[j]);}
    double slope(int j1,int j2){return (Y(j1)-Y(j2))/(X(j2)-X(j1));}
    
    int head,tail,list[110000];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        s[0]=0;
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]), s[i]=s[i-1]+a[i];
        
        memset(f,0,sizeof(f));now=0;
        for(int t=1;t<=m;t++)//第t次 cut 
        {
            now^=1;
            head=1,tail=1;list[head]=t;
            for(int i=t+1;i<=n;i++)
            {
                while(head!=tail&&(slope(list[head],list[head+1])<double(s[i])||s[list[head]]==s[list[head+1]]))head++;
                int j=list[head];
                f[i][now]=f[j][now^1]+s[j]*(s[i]-s[j]);
                while(head!=tail&&(s[i]==s[list[tail]]||slope(list[tail-1],list[tail])>slope(list[tail],i)))tail--;
                list[++tail]=i;
            }
        }
        printf("%lld
    ",f[n][now]);
        return 0;
    }
  • 相关阅读:
    Python性能鸡汤
    postgreSQL设置自增长字段并插入值
    DBSCAN算法的Java,C++,Python实现
    查看进程及端口使用情况
    软件工程中的各种图
    程序员技术练级攻略[转]
    CSS中 opacity的设置影响了index(层数)的改变
    页面预加载loading动画
    JS 判断用户使用的设备类型
    图片懒加载——介绍
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8576021.html
Copyright © 2020-2023  润新知