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;
    }
  • 相关阅读:
    将浏览器变成文本编辑器
    《奋斗吧!菜鸟》 第七次作业:团队项目设计完善&编码
    java第二周作业
    java第一周作业
    java第三周作业
    java暑期作业
    java第四周学习总结
    正则表达式常用的js验证
    学习网址
    jquery 操作下拉框
  • 原文地址:https://www.cnblogs.com/HooYing/p/10951343.html
Copyright © 2011-2022 走看看