• 洛谷3195(HNOI2008)玩具装箱


    题目:https://www.luogu.org/problemnew/show/P3195

    自己做斜率优化的第一道题。

    推成斜率优化的样子很重要。

      斜率优化的样子就是从 j 中求 i 的话,关系式里一个量只和 i 有关,一个量只和 j 有关,一个量同时和 i 与 j 有关。

      这时可以把那个 同时和 i 与 j 有关的量 里的和 j 有关的量看成 x[ j ],把只和 j 有关的量看成 y[ j ],然后只和 i 有关的量就是截距、x[ j ]前面的就是式子里的斜率。

    (为了推出这样的式子,可以设a,b等等,帮助自己推。大体思路是将与 i 或 j 或 i 和 j 有关的东西看成一个整体)

    推出式子以后,找合适的 j 就是 j - 1 与 j 的斜率比式子里的斜率大(或小),而 j 与 j + 1 的斜率比式子里的斜率小(或大)的那个 j 。

    找到 j 以后把式子变变形就得到推出dp[ i ] 的式子了。

    可用单调队列。

    把a什么的写成函数很方便。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    #define db double
    using namespace std;
    const int N=50005;
    int n,L,h=1,t=1,q[N];
    ll s[N],dp[N];
    db a(int i){return s[i]+i;}
    db b(int i){return s[i]+i+L+1;}
    db x(int i){return b(i);}
    db y(int i){return b(i)*b(i)+dp[i];}
    db slope(int j,int i){return (y(i)-y(j))/(x(i)-x(j));}
    int main()
    {
        scanf("%d%d",&n,&L);ll z;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&z);s[i]=s[i-1]+z;
        }
        for(int i=1;i<=n;i++)
        {
            while(h<t&&slope(q[h],q[h+1])<2*a(i))h++;
            dp[i]=(a(i)-b(q[h]))*(a(i)-b(q[h]))+dp[q[h]];
            while(t>h&&slope(q[t-1],q[t])>slope(q[t-1],i))t--;
            q[++t]=i;
        }
        printf("%lld",dp[n]);
        return 0;
    }
  • 相关阅读:
    HashCode和equal方法
    Quartz.NET 学习笔记整理(一)
    XAML学习笔记(一)
    【转】21个经典的哲理故事
    关于List<T>集合中的差集
    batch files
    Maintenance Plans in MS SQL 2005
    Telerik
    What is DeltaCopy
    How to Insert Values into an Identity Column in SQL Server
  • 原文地址:https://www.cnblogs.com/Narh/p/9139814.html
Copyright © 2020-2023  润新知