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;
}

posted @ 2025-10-23 10:45  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源