BZOJ4884 [Lydsy2017年5月月赛]太空猫

时间:2023-01-12 19:17:13

这个傻逼题……比赛的时候读出了三种题意,然后各写了一遍结果全wa了,后来才被告知有坑点……

题意:操作有三种,可以向左或向右移动一格,或者重力反转,操作只能在落地之后再进行,问到终点的最小代价

容易看出向左走蛋用没有

f[i][0/1]表示走到第i列,重力向下/上的最小代价,随便转移即可

坑点就是前一列的下边界比后一列的上边界高或者前一列的上边界比后一列的下边界低

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<map>
#include<bitset>
#include<stack>
#include<vector>
#include<set>
using namespace std;
#define MAXN 100010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define ll long long
#define eps 1e-8
ll f[MAXN][2];
int l[MAXN],r[MAXN];
int n;
int main(){
	int i;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&r[i]);
	}
	for(i=1;i<=n;i++){
		scanf("%d",&l[i]);
	}
	for(i=1;i<n;i++){
		if(l[i]>=r[i+1]||r[i]<=l[i+1]){
			printf("-1\n");
			return 0;
		}
		
	}
	memset(f,0x3f,sizeof(f));
	f[1][0]=0;
	for(i=1;i<=n;i++){
		ll t0=f[i][0],t1=f[i][1];
		f[i][0]=min(f[i][0],t1+r[i]-l[i]);
		f[i][1]=min(f[i][1],t0+r[i]-l[i]);
		if(f[i][0]>1e18&&f[i][1]<1e18){
			printf("-1\n");
			return 0;
		}
		if(r[i+1]>=r[i]){
			f[i+1][1]=f[i][1];
		}
		if(l[i+1]<=l[i]){
			f[i+1][0]=f[i][0];
		}
	}
	printf("%lld\n",f[n][0]);
	return 0;
}

/*

*/