mini notes

競技プログラミングの解法メモを残していきます。

DPまとめコンテスト  A - Frog 1

A - Frog 1

概要

数列h_{N}がある。この数列を0つとばし、1つとばしのどちらかで進む。
h_{i}からh_{j}に進むとき、コストが|h_{j}-h_{i}|かかる。
h_{1}からh_{N}に進むときのコストの総和の最小値を求めよ。

制約

2 \leq N \leq 10^{5}
1 \leq h_{i} \leq 10^{4}

方針

コストを配列にする。
h_{i}まで進むときの最小コストをc[i]とすると、c[i]は下記の通り遷移する。
c[i+1] = \min(c[i-1] + |h_{i+1} - h_{i-1}|, c[i] + |h_{i+1} - h_{i}|)

解答

Submission #3938370 - Educational DP Contest / DP まとめコンテスト

#include <bits/stdc++.h>
 
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define rep(i,n) FOR(i,0,n)
#define RFOR(i,a,b) for(int i=(a)-1;i>=(b);i--)
#define rrep(i,n) RFOR(i,n,0)
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
 
	int n;
	cin >> n;
 
	ll h[n];
	rep(i, n) cin >> h[i];
 
	ll c[n];
	c[0] = 0;
	c[1] = abs(h[1] - h[0]);
	for(int i = 1; i+1 <= n-1; i++){
		c[i+1] = min(c[i-1] + abs(h[i+1] - h[i-1]), c[i] + abs(h[i+1] - h[i]));
	}
 
	cout << c[n-1] << endl;
}