zoukankan      html  css  js  c++  java
  • Print Article

    题目链接:https://vjudge.net/problem/HDU-3507#author=0

    题意:给出n个数,要求按顺序全部取出,每次取出一段所花费的费用为取出一段数的和的平方加m,问最小费用是多少。

    思路:很容易想到一个O(n2)的做法,dp[i]=dp[j]+(sum[i]-sum[j])2+m;但n有5*105,肯定会超时。这是就要进行化简了。

    可以假设在求dp[i]是,dp[i]由dp[j]转换而来比由dp[k]转换来更优,(j>k)。

    那dp[j]+(sum[i]-sum[j])2+m<=dp[k]+(sum[i]-sum[k])2+m

    化简得(dp[j]+sum[j]2)-(dp[k]+sum[k]2)/(2*(sum[j]-sum[k]))<=sum[i]

    如果上试成立的话,那j点就比k点更优,可以把k点淘汰掉。

    令:yj=dp[j]+sum[j]*sum[j]   xj=2*sum[j]

    (yj-yk)/(xj-xk) <= sum[i];

    令g[k,j]=(yj-yk)/(xj-xk)

    如果对于k<j<i,g[k,j]>g[j,i] 那么 j 也是可以淘汰的。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll dp[500005],sum[500005],q[500005];
    ll getx(ll x)
    {
        return 2*sum[x];
    }
    ll gety(ll x)
    {
        return dp[x]+sum[x]*sum[x];
    }
    bool cross(ll x1,ll y1,ll x2,ll y2,ll x3,ll y3)
    {
        ll ans=(y3-y1)*(x2-x1)-(y2-y1)*(x3-x1);
        if(ans<=0ll)
            return true;
        return false;
    }
    bool fun(ll x,ll y,ll i)
    {
        if( (dp[x]+sum[x]*sum[x])-(dp[y]+sum[y]*sum[y]) <=2*sum[i]*(sum[x]-sum[y]) )
            return true;
        return false;
    }
    int main()
    {
        ll n,m;
        while(~scanf("%lld%lld",&n,&m))
        {
            for(int i=1; i<=n; i++)
            {
                ll x;
                cin>>x;
                sum[i]=sum[i-1]+x;
                dp[i]=0;
            }
            int head=0,tail=1;
            q[0]=0;
            for(int i=1; i<=n; i++)
            {
                while((head+1<tail)&&fun(q[head+1],q[head],i))
                    head++;
                ll x=q[head];
                dp[i]=dp[x]+(sum[i]-sum[x])*(sum[i]-sum[x])+m;
                while((head+1<tail)&&cross(getx(q[tail-2]),gety(q[tail-2]),getx(q[tail-1]),gety(q[tail-1]),getx(i),gety(i)) )
                    tail--;
                q[tail++]=i;
            }
            cout<<dp[n]<<endl;
        }
    }
    

      

  • 相关阅读:
    Java
    Java
    SpringBoot
    面对 DDoS 攻击,我们能做些什么?
    instanceof运算符的实质:Java继承链与JavaScript原型链
    从λ演算到函数式编程聊闭包(1):闭包概念在Java/PHP/JS中形式
    JIT-动态编译与AOT-静态编译:java/ java/ JavaScript/Dart乱谈
    JS遍历循环方法性能对比:for/while/for in/for of/map/foreach/every
    线程池的使用示例-批量查询
    国企离职鸡飞狗跳记
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/13708786.html
Copyright © 2011-2022 走看看