zoukankan      html  css  js  c++  java
  • Print Article(斜率DP入门+单调队列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3507

    题目大意:给你n个数,然后问你怎么分割当前的这n个数位那几组,使得每一组的权值加起来最大。每一组权值的计算方法在题目上说了。

    具体思路: 一开始打了一波两重for循环的,一直求一个tile,但是wa了。然后就学了斜率优化的方法

    https://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html

    就是把表达式转换成斜率类型的表达式,然后对于当前的节点,通过判断斜率的方式来决定当前的点是不是该选择,这个过程可以用单调队列维护。

    AC代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cmath>
     4 using namespace std;
     5 # define ll long long
     6 const int maxn = 6e5+100;
     7 int sum[maxn];
     8 int q[maxn];
     9 int dp[maxn];
    10 int n,m;
    11 int getdp(int i,int j){
    12 return dp[i]+m+(sum[j]-sum[i])*(sum[j]-sum[i]);
    13 }
    14 int getup(int i,int j){
    15 return dp[i]+sum[i]*sum[i]-(dp[j]+sum[j]*sum[j]);
    16 }
    17 int getdown(int i,int j){
    18 return 2*(sum[i]-sum[j]);
    19 }
    20 int main(){
    21 while(~scanf("%d %d",&n,&m)){
    22 for(int i=1;i<=n;i++){
    23 scanf("%d",&sum[i]);
    24 sum[i]+=sum[i-1];
    25 }
    26 int tail,head;
    27 tail=head=0;
    28 q[tail++]=0;
    29 
    30 for(int i=1;i<=n;i++){
    31 while(head+1<tail&&getup(q[head+1],q[head])<=sum[i]*getdown(q[head+1],q[head]))head++;
    32 dp[i]=getdp(q[head],i);
    33 while(head+1<tail&&getdown(q[tail-2],q[tail-1])*getup(q[tail-1],i)<=getdown(q[tail-1],i)*getup(q[tail-2],q[tail-1]))tail--;
    34 q[tail++]=i;
    35 }
    36 printf("%d
    ",dp[n]);
    37 }
    38 return 0;
    39 }
  • 相关阅读:
    大数据-数据分析-numpy库-数组的深拷贝和浅拷贝
    windows环境下mysql主从配置
    C#定时发送邮箱设置
    论《LEFT JOIN条件放ON和WHERE后的区别》
    记录成长
    RobotFramework+Selenium如何提高脚本稳定性
    Jekins 插件Extended Choice Parameter显示Json Parameter Type遇到的问题
    nGrinder 参数使用
    Jenkins REST API 实例
    java ee config / nacos / shit Alibaba Middleware
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10558822.html
Copyright © 2011-2022 走看看