zoukankan      html  css  js  c++  java
  • hdu 3507 Print Article(斜率优化dp入门题)

    题意:输入n个数字,将其分成几组,每一组算出其和的平方加上m,将每一组的值求和,求这个和的最小值

    dp方程:dp[i]=min{dp[j]+(S[i]S[j])^2+m}(j<i)

    这里要用斜率来优化才能用单调队列

    这篇博客讲的很不错了:https://www.cnblogs.com/orzzz/p/7885971.html

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxx = 500010;
    int q[maxx];//存下标
    LL sum[maxx],dp[maxx];
    //dp[i]=min(dp[j]+m+(sum[i]-sum[j])^2)
    int n,m;
    LL getup(int j,int k)
    {
        return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]);
    }
    LL getdown(int j,int k)
    {
        return sum[j]-sum[k];
    }
    LL getdp(int i,int j)
    {
        return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            LL t;
            dp[0]=sum[0]=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%lld",&t);
                sum[i]=sum[i-1]+t;
            }
            int l=1,r=1;
            q[r]=0;
            for(int i=1;i<=n;i++)
            {
                while(l+1<=r&&getup(q[l+1],q[l])<=2*sum[i]*getdown(q[l+1],q[l]))l++;
                dp[i]=getdp(i,q[l]);
                //维护下凸
                while(l+1<=r&&getup(i,q[r])*getdown(q[r],q[r-1])<=getup(q[r],q[r-1])*getdown(i,q[r]))r--;
                q[++r]=i;
            }
            printf("%lld
    ",dp[n]);
        }
        return 0;
    }
  • 相关阅读:
    【MyLocations】标记位置App开发体会
    iOS开发-Core Location和Map Kit
    iOS开发-轻点、触摸和手势
    iOS开发-GCD和后台处理
    iOS开发-block使用与多线程
    iOS开发-数据持久化
    iOS开发-为程序添加应用设置
    对iOS中MVC的理解
    docker
    linux shell
  • 原文地址:https://www.cnblogs.com/HooYing/p/10951343.html
Copyright © 2011-2022 走看看