mirror of
https://github.com/Kiritow/OJ-Problems-Source.git
synced 2024-03-22 13:11:29 +08:00
72 lines
1.9 KiB
C++
72 lines
1.9 KiB
C++
|
#include <cstdio>
|
|||
|
#include <cstdlib>
|
|||
|
#include <cstring>
|
|||
|
#include <algorithm>
|
|||
|
using namespace std;
|
|||
|
|
|||
|
#define MAXN 50100
|
|||
|
#define MAXH 110
|
|||
|
#define MAXVAL_H 100
|
|||
|
#define INF 0x3f3f3f3f
|
|||
|
|
|||
|
int dp[2][MAXH];
|
|||
|
int bus[MAXH];
|
|||
|
|
|||
|
int main()
|
|||
|
{
|
|||
|
int N,C;
|
|||
|
while(scanf("%d %d",&N,&C)==2)
|
|||
|
{
|
|||
|
/// Main Loop
|
|||
|
int x;
|
|||
|
scanf("%d",&x);
|
|||
|
int index=0;
|
|||
|
///由于人无法变矮,因此这部分的花费记为INF
|
|||
|
for(int i=0;i<x;i++) dp[index][i]=INF;
|
|||
|
///大于等于x的时候可以内增高呀!
|
|||
|
for(int i=x;i<=MAXVAL_H;i++) dp[index][i]=(i-x)*(i-x);
|
|||
|
N--;
|
|||
|
while(N--)
|
|||
|
{
|
|||
|
///登记一个新的身高x
|
|||
|
scanf("%d",&x);
|
|||
|
index=!index;///反转index(复用dp空间)
|
|||
|
int begin=0;
|
|||
|
int end=0;
|
|||
|
/// 单调队列 方向: 小(0) --> 大(N)
|
|||
|
for(int k=0;k<=MAXVAL_H;k++)
|
|||
|
{
|
|||
|
int cost=dp[!index][k]-k*C;
|
|||
|
/// Pop Back
|
|||
|
while(begin<end&& bus[end-1] > cost) end--;
|
|||
|
/// Push Back
|
|||
|
bus[end++]=cost;
|
|||
|
if(k<x) {dp[index][k]=INF;}
|
|||
|
///队列最前面是值最小的
|
|||
|
else {dp[index][k]=bus[begin]+k*C+(k-x)*(k-x);}
|
|||
|
}
|
|||
|
/// Empty
|
|||
|
begin=end=0;
|
|||
|
for(int k=MAXVAL_H;k>=0;k--)
|
|||
|
{
|
|||
|
int cost=dp[!index][k]+k*C;
|
|||
|
/// Pop Back
|
|||
|
while(begin<end&&bus[end-1] > cost) end--;
|
|||
|
/// Push Back
|
|||
|
bus[end++]=cost;
|
|||
|
if(k>=x)
|
|||
|
{
|
|||
|
dp[index][k]=min(dp[index][k],bus[begin]-k*C+(k-x)*(k-x));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
int ans=INF;
|
|||
|
for(int i=0;i<=MAXVAL_H;i++)
|
|||
|
{
|
|||
|
ans=min(dp[index][i],ans);
|
|||
|
}
|
|||
|
printf("%d\n",ans);
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|