zoukankan      html  css  js  c++  java
  • 【BZOJ 3156】防御准备

    【链接】 链接
    【题意】

    在这里输入题意

    【题解】

    把a倒过来 设f[i]表示在i放一个防御塔的最小花费; 我们如果从j转移过来 就表示j+1..i-1这一段放人偶。 s[i] = 1 + 2 + ... + i; 则 $f[i] = fj + (s[i-1]-s[j]) -(i-1-j)*j + a[i]$ 做一下斜率优化就好。 因为我们第一段可能一开始没有放防御塔。 所以先假设在第n个位置放了一个防御塔。 再枚举最后一段没放防御塔的情况。

    【错的次数】

    在这里输入错的次数

    【反思】

    转移方程那里一开始写成s[i-1]-s[j]了。。。错误地认为是i+1..j这一段了。而实际上是i+1..j-1这一段。

    【代码】

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int N = 1e6;
    
    int n,dl[N+10],h,t;
    ll a[N+10],f[N+10],s[N+10];
    
    double ju(int x,int y)
    {
        double fenzi = f[y]-s[y]+1LL*y*y+y-(f[x]-s[x]+1LL*x*x+x);
        double fenmu = y-x;
        return fenzi/fenmu;
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
    
        scanf("%d",&n);
        for (int i = n;i >= 1;i--) scanf("%lld",&a[i]);
        for (int i = 1;i <= n;i++) s[i] = s[i-1] + i;
    
        f[1] = a[1];
    
        h = t = 1;
        dl[1] = 1;
        for (int i = 2;i <= n;i++)
        {
            while (h < t && ju(dl[h],dl[h+1]) < i) h++;
            int j = dl[h];
            f[i] = f[j] + (s[i-1]-s[j])-1LL*(i-1-j)*j + a[i];
            while (h < t && ju(dl[t-1],dl[t]) > ju(dl[t],i)) t--;
            dl[++t] = i;
        }
    
        ll ans = f[n];
        for (int i = 1;i<=n-1;i++)
            ans=min(ans,f[i]+s[n]-s[i]-1LL*(n-i)*i);
    
        printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    第09组 Beta冲刺(2/5)
    第09组 Beta冲刺(3/5)
    第09组 Beta冲刺(4/5)
    第09组 Beta冲刺(5/5)
    第09组 Beta冲刺(1/5)
    SDN课程阅读作业(2)
    C语言I作业07
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业03
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7643975.html
Copyright © 2011-2022 走看看