• bzoj 3156 防御准备(斜率DP)


    3156: 防御准备

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 837  Solved: 395
    [Submit][Status][Discuss]

    Description

     

    Input

    第一行为一个整数N表示战线的总长度。

    第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai。

    Output

    共一个整数,表示最小的战线花费值。

    Sample Input



    10
    2 3 1 5 4 5 6 3 1 2

    Sample Output


    18

    HINT



    1<=N<=10^6,1<=Ai<=10^9

    Source

    【思路】

           斜率优化DP。

           唯一需要注意的是过程中数据超范围,需要特别声明一下。

       为毛斜率DP都长一个样<_<

    【代码1】

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 
     5 typedef long long LL; 
     6 const int N = 1e6+10;
     7 struct point { LL x,y;
     8 }q[N],now;
     9 int n,L,R,a[N];
    10 
    11 LL cross(point a,point b,point c) {
    12     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
    13 }
    14 void read(int& x) {
    15     char c=getchar(); while(!isdigit(c)) c=getchar();
    16     x=0; while(isdigit(c)) x=x*10+c-'0' , c=getchar();
    17 }
    18 int main() {
    19     //freopen("in.in","r",stdin);
    20     //freopen("out.out","w",stdout);
    21     read(n); 
    22     for(int i=1;i<=n;i++) read(a[i]);
    23     for(int i=1;i<=n;i++) {
    24         while(L<R && q[L].y-q[L].x*i >= q[L+1].y-q[L+1].x*i) L++;
    25         now.x=i;
    26         now.y=q[L].y-(LL)q[L].x*i+(LL)i*i+a[i];
    27         while(L<R && cross(q[R-1],q[R],now)<=0) R--;
    28         q[++R]=now;
    29     }
    30     printf("%lld",q[R].y-(LL)n*(n+1)/2);    // (LL) n*(n+1)/2
    31     return 0;
    32 }
    Folding 1

    【代码2】

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 
     6 typedef long long LL;
     7 const int N = 1e6+10;
     8 
     9 int n,L,R,a[N],q[N]; LL f[N]; 
    10 
    11 double slop(int k,int j) {
    12     return (double)(f[j]-f[k]+(LL)j*(j+1)/2-(LL)k*(k+1)/2)/(j-k);
    13 }
    14 void read(int& x) {
    15     char c=getchar(); while(!isdigit(c)) c=getchar();
    16     x=0; while(isdigit(c)) x=x*10+c-'0' , c=getchar();
    17 }
    18 int main() {
    19     //freopen("in.in","r",stdin);
    20     //freopen("out.out","w",stdout);
    21     read(n);
    22     for(int i=1;i<=n;i++) read(a[i]);
    23     for(int i=1;i<=n;i++) {
    24         while(L<R && slop(q[L],q[L+1])<i) L++;
    25         int t=q[L];
    26         f[i]=f[t]+(LL)i*(i-t)+(LL)t*(t+1)/2-(LL)i*(i+1)/2+a[i];
    27         while(L<R && slop(q[R-1],q[R])>slop(q[R],i)) R--;
    28         q[++R]=i;
    29     }
    30     printf("%lld",f[n]);
    31     return 0;
    32 }
    Folding 2
  • 相关阅读:
    转 oracle catalog 库常用脚本
    转 【ORACLE】ORA-12537 问题整理
    转 Trace a specific ORA- error
    15%
    MySQL 存储过程
    MySQL 命令行客户机的分隔符
    MySQL 连接join
    MySQL 正则表达式
    MySQL 日期时间函数
    Arthas 快速入门
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5118711.html
Copyright © 2020-2023  润新知