题目链接
解题思路
一道简单的线性DP
设置状态
设
f
[
i
]
f[i]
f[i]表示到达“在
i
i
i点,重力向下”这一状态时的能量消耗最小值
同样地,设
g
[
i
]
g[i]
g[i]表示到达“在
i
i
i点,重力向上”这一状态时的能量消耗最小值
转移方程
f
[
i
]
f[i]
f[i]由
f
[
i
−
1
]
f[i-1]
f[i−1]可转移得来:若下边界非升,则
f
[
i
]
=
f
[
i
−
1
]
f[i]=f[i-1]
f[i]=f[i−1]
g
[
i
]
g[i]
g[i]由
g
[
i
−
1
]
g[i-1]
g[i−1]可转移得来:若上边界非降,则
g
[
i
]
=
g
[
i
−
1
g[i]=g[i-1
g[i]=g[i−1
然后?
考虑重力反转的情况
设
w
i
w_i
wi为i点高度差
则
f
[
i
]
=
m
i
n
(
f
[
i
]
,
g
[
i
]
+
w
i
)
f[i]=min(f[i],g[i]+w_i)
f[i]=min(f[i],g[i]+wi)
g
[
i
]
=
m
i
n
(
g
[
i
]
,
f
[
i
]
+
w
i
)
g[i]=min(g[i],f[i]+w_i)
g[i]=min(g[i],f[i]+wi)
TIP:这题最大的坑点:要注意
i
−
1
i-1
i−1的上边界
≤
\leq
≤
i
i
i的下边界、
i
−
1
i-1
i−1的下边界
≥
\geq
≥
i
i
i的上边界两种情况,这时候应直接输出-1,结束程序
初始赋值
f
[
1
]
=
0
f[1]=0
f[1]=0,其余
f
[
i
]
=
I
N
F
f[i]=INF
f[i]=INF
g
[
1
]
=
w
1
g[1]=w_1
g[1]=w1,其余
g
[
i
]
=
I
N
F
g[i]=INF
g[i]=INF
答案存储
存储在 f [ n ] f[n] f[n]里
详细代码
#define rg register
#define il inline
#define DEBUG printf("[Passing [%s] in line %d.]\n", __func__, __LINE__)
#define putline putchar('\n')
#define putsp putchar(' ')
#define Rep(a, s, t) for(rg int a = s; a <= t; a++)
#define Repdown(a, t, s) for(rg int a = t; a >= s; a--)
typedef long long ll;
#include<cstdio>
#define rs freopen("test.in", "r", stdin), freopen("test.out", "w", stdout)
struct IO
{
IO(int set = 0) {if(set) rs;}
template<typename T> il IO r(T& x)const
{
x = 0; T f = 1; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + int(ch - '0');
x *= f; return *this;
}
template<typename T> il IO w(T x)const
{
if(x < 0) {putchar('-'); x = -x;}
if(x >= 10) w(x / 10);
putchar(x % 10 + '0'); return *this;
}
template<typename T> il IO wl(const T& x)const {w(x), putline; return *this;}
template<typename T> il IO ws(const T& x)const {w(x), putsp; return *this;}
il IO l() {putline; return *this;}
il IO s() {putline; return *this;}
}io;
template<typename T> il T Max(const T& x, const T& y) {return y < x ? x : y;}
template<typename T> il T Min(const T& x, const T& y) {return y < x ? y : x;}
template<typename T> il void Swap(T& x, T& y) {T tmp = x; x = y; y = tmp;}
/*
a:上边界
b:下边界
f[i]:猫在i位置, 且重力向下
g[i]: 猫在i位置, 且重量向上
if(c[i-1]<=c[i]) f[i] = f[i - 1] else f[i] = INF
if(d[i-1]>=d[i]) g[i] = g[i - 1] else g[i] = INF
f[i] = min(f[i], g[i] + w)
g[i] = min(g[i], f[i] + w)
*/
const ll INF = 0x7fffffffffffffll;
const ll MAXN = 1000005;
ll n;
ll a[MAXN], b[MAXN], f[MAXN], g[MAXN];
int main()
{
//FileReset();
io.r(n);
for(rg int i = 1; i <= n; i++) io.r(a[i]), f[i] = INF;
for(rg int i = 1; i <= n; i++) io.r(b[i]), g[i] = INF;
f[1] = 0;
g[1] = a[1] - b[1];
for(rg int i = 2; i <= n; i++)
{
if(a[i - 1] <= a[i]) g[i] = g[i - 1];
if(b[i - 1] >= b[i]) f[i] = f[i - 1];
if(a[i - 1] <= b[i] || b[i - 1] >= a[i]) {io.wl(-1); return 0;}
ll w = a[i] - b[i];
f[i] = Min(f[i], g[i] + w);
g[i] = Min(g[i], f[i] + w);
}
io.wl(f[n] == INF ? -1 : f[n]);
return 0;
}