zoukankan      html  css  js  c++  java
  • bzoj3156: 防御准备

    为什么我又是一眼秒算法然后搞了这么久。。。一开始还想了个二维。。。

    那么这题DP方程很好写:f[i]=min{a[i]+f[j]+(i-j)*(i-j+1)/2}

    ans=min{f[i]+(n-i)*(n-i+1)/2}

    明显有单调性

    那么可以化出 ((2*f[j1]+j1^2)-(2*f[j2]+j2^2)) / (j1-j2) <=2*i+1

    优化到O(n)

    #include<cstdio>
    #include<iostream> 
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    
    LL a[1100000],f[1100000];
    
    double slope(LL j1,LL j2)
    {
        return ( (double(2*f[j1]+j1*j1)-double(2*f[j2]+j2*j2)) )/( (double(j1))-(double(j2)) );
    }
    LL list[1100000];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lld",&a[n-i+1]);
        
        f[1]=a[1];LL ans=f[1]+(LL(n-1))*(LL(n-1+1))/2;
        int head=1,tail=1;list[1]=1;
        for(int i=2;i<=n;i++)
        {
            while(head<tail&&slope(list[head],list[head+1])<=(double(2*i-1)))head++;
            int j=list[head];
            f[i]=f[j]+a[i]+(LL(i-1-j))*(LL(i-j))/2LL;
            ans=min(ans,f[i]+(LL(n-i))*(LL(n-i+1))/2);
            while(head<tail&&slope(list[tail-1],list[tail])>=slope(list[tail],i))tail--;
            list[++tail]=i;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    每日算法
    每日算法
    搜索算法入门详解
    NLP
    每日算法
    每日算法
    Elasticsearch地理位置总结
    elasticsearch Geo Bounding Box Query
    elasticsearch Geo Distance Query
    Elasticsearch java API (23)查询 DSL Geo查询
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8949282.html
Copyright © 2011-2022 走看看