BZOJ4884: [Lydsy1705月赛]太空猫解题报告

题目链接

解题思路

一道简单的线性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[i1]可转移得来:若下边界非升,则 f [ i ] = f [ i − 1 ] f[i]=f[i-1] f[i]=f[i1]
g [ i ] g[i] g[i] g [ i − 1 ] g[i-1] g[i1]可转移得来:若上边界非降,则 g [ i ] = g [ i − 1 g[i]=g[i-1 g[i]=g[i1
然后?
考虑重力反转的情况
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 i1的上边界 ≤ \leq i i i的下边界、 i − 1 i-1 i1的下边界 ≥ \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;
}














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日居月诸Rijuyuezhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值