码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 3156: 防御准备

时间:2017-09-05 21:54:42      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:png   div   size   int   es2017   转移   problem   center   sum   

3156: 防御准备

Time Limit: 10 Sec  Memory Limit: 512 MB
[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

 

枚举上一个守卫塔建在哪儿转移DP

斜率优化

 

#include<cstdio>
#include<iostream>
#define N 1000001
using namespace std;
long long sum[N],dp[N];
int a[N];
int head,tail,q[N];
void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c))  c=getchar();
    while(isdigit(c)) { x=x*10+c-0; c=getchar(); }
}
long long up(int k,int j)
{
    return dp[j]-dp[k]+sum[j]-sum[k];
}
long long down(int k,int j)
{
    return j-k;
}
int main()
{
    int n;
    read(n);
    for(int i=1;i<=n;i++) read(a[i]),sum[i]=sum[i-1]+i;
    int j;
    for(int i=1;i<=n;i++)
    {
        while(head<tail && up(q[head],q[head+1])<=down(q[head],q[head+1])*i) head++;
        j=q[head];
        dp[i]=dp[j]+1ll*i*(i-j)-sum[i]+sum[j]+a[i];
        while(head<tail && up(q[tail-1],q[tail])*down(q[tail],i)>=up(q[tail],i)*down(q[tail-1],q[tail])) tail--;
        q[++tail]=i;
    }
    printf("%lld",dp[n]);
}

 

bzoj 3156: 防御准备

标签:png   div   size   int   es2017   转移   problem   center   sum   

原文地址:http://www.cnblogs.com/TheRoadToTheGold/p/7481820.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!