zoukankan      html  css  js  c++  java
  • BZOJ3156 防御准备(动态规划+斜率优化)

      设f[i]为在i放置守卫塔时1~i的最小花费。那么显然f[i]=min(f[j]+(i-j)*(i-j-1)/2)+a[i]。

      显然这是个斜率优化入门题。将不与i、j同时相关的提出,得f[i]=min(f[j]+j*(j+1)/2-ij)+i*(i-1)/2+a[i]。

      套路地,假设j>k且j转移优于k,则f[j]+j*(j+1)/2-ij<f[k]+k*(k+1)/2-ik,(f[j]+j*(j+1)/2-f[k]-k*(k+1)/2)/(j-k)<i。

      维护下凸壳即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 1000010
    #define ll long long
    int n,a[N],q[N];
    ll f[N];
    long double calc(int j,int k)
    {
        return (long double)(f[j]+(1ll*j*(j+1)>>1)-f[k]-(1ll*k*(k+1)>>1))/(j-k);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3156.in","r",stdin);
        freopen("bzoj3156.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++) a[i]=read();
        f[0]=0;
        int head=1,tail=1;q[1]=0;
        for (int i=1;i<=n;i++)
        {
            while (head<tail&&calc(q[head],q[head+1])<i) head++;
            f[i]=f[q[head]]+(1ll*q[head]*(q[head]+1)>>1)-1ll*i*q[head]+(1ll*i*(i-1)>>1)+a[i];
            while (head<tail&&calc(q[tail-1],q[tail])>calc(q[tail],i)) tail--;
            q[++tail]=i;
        }
        cout<<f[n];
        return 0;
    }
  • 相关阅读:
    PHP 抽象类
    PHP使用rabbitmq发邮件简单使用
    自定义Chrome插件Vimium
    用Paint Tool SAI绘制漫画
    AutoHotkey 使用笔记
    Unity 性能
    VS2015解决非Unicode编码包含中文字段无法编译的问题
    高DPI设置时禁用显示的方法
    Excel 统计在某个区间内数值的个数
    自定义宏把Word打造成全快捷键编辑器
  • 原文地址:https://www.cnblogs.com/Gloid/p/9665314.html
Copyright © 2011-2022 走看看