AT_dp_z Frog 3题解
题目描述
有 N 个台阶。每个台阶编号为 1,2,…,N。对于每个 i(1≤i≤N),第 i 个台阶的高度为 hi。已知 h1<h2<⋯<hN。
一只青蛙最初在台阶 1 上。青蛙可以多次进行如下操作,试图到达台阶 N:
- 当青蛙在台阶 i 时,可以跳到台阶 i+1,i+2,…,N 中的任意一个。若跳到台阶 j,则需要支付的代价为 (hj−hi)2+C。
请你求出青蛙到达台阶 N 所需支付的总代价的最小值。
输入格式
输入以如下格式从标准输入给出。
N C h1 h2 … hN
输出格式
输出青蛙所需支付的总代价的最小值。
显示翻译
题意翻译
输入输出样例
输入 #1复制
5 6 1 2 3 4 5
输出 #1复制
20
输入 #2复制
2 1000000000000 500000 1000000
输出 #2复制
1250000000000
输入 #3复制
8 5 1 3 4 5 10 11 12 13
输出 #3复制
62
说明/提示
限制条件
- 所有输入均为整数。
- 2≤N≤2×105
- 1≤C≤1012
- 1≤h1<h2<⋯<hN≤106
样例解释 1
若青蛙依次跳到台阶 1→3→5,总代价为 ((3−1)2+6)+((5−3)2+6)=20。
样例解释 2
答案可能超出 32 位整数范围。
样例解释 3
若青蛙依次跳到台阶 1→2→4→5→8,总代价为 ((3−1)2+5)+((5−3)2+5)+((10−5)2+5)+((13−10)2+5)=62。
由 ChatGPT 4.1 翻译
思路
斜率优化DP。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,m,a[200005],f[200005],f2[200005],q[200005],l1=1,r1=1;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
memset(f,0x7f7f7f7f,sizeof(f));
memset(f2,0x7f7f7f7f,sizeof(f2));
f[1]=0;
q[l1]=1;
for(int i=2;i<=n;i++){
while(r1>=l1+1&&(long double)(f[q[l1+1]]-f[q[l1]]+a[q[l1+1]]*a[q[l1+1]]-a[q[l1]]*a[q[l1]])/(long double)(a[q[l1+1]]-a[q[l1]])<=2*a[i]){
l1++;
}
f[i]=f[q[l1]]+m+(a[i]-a[q[l1]])*(a[i]-a[q[l1]]);
while((long double)(f[i]+a[i]*a[i]-f[q[r1]]-a[q[r1]]*a[q[r1]])/(long double)(a[i]-a[q[r1]])<=(long double)(f[q[r1]]+a[q[r1]]*a[q[r1]]-f[q[r1-1]]-a[q[r1-1]]*a[q[r1-1]])/(long double)(a[q[r1]]-a[q[r1-1]])&&r1>=l1+1){
r1--;
}
q[++r1]=i;
//cout<<f[i]<<endl;
}
cout<<f[n]<<endl;
return 0;
}

浙公网安备 33010602011771号