4884: [Lydsy2017年5月月賽]太空貓
Time Limit: 1 Sec Memory Limit: 256 MB
Submit: 505 Solved: 145
[Submit][Status][Discuss]
Description
太空貓(SpaceCat)是一款畫面精緻、玩法有趣的休閒遊戲,你需要控制一隻坐在迷你飛碟上的貓咪在太空裏不斷探
索,讓大家看看你能飛得多遠。遊戲地圖可以看成一個二維的網格圖,上下是兩段障礙物。在遊戲的一開始,太空
貓位於地圖最左邊的下邊界之上,且重力方向向下。
在每個時刻,你可以用手指點擊屏幕,翻轉重力的方向,或者通過遙感控制太空貓往左或往右移動。每次翻轉重力
方向時,你需要消耗的能量值等於上下底邊之間的高度差。在左右移動的時候,太空貓可以下降到對應重力方向更
低的位置,但不能往上爬。當然,太空貓也不能穿牆而過。在重力翻轉的過程中,直到碰到地面之前,你都不能操
控太空貓左右移動。太空貓的終點位於地圖的最右端的下底邊之上,請計算爲了讓太空貓到達終點,需要消耗能量
的最小值。
Input
第一行包含一個正整數n(1<=n<=100000),即地圖的寬度。
第二行包含n個正整數c_1,c_2,…,c_n(2<=c_i<=10^9),分別表示每個橫座標對應的上邊界的高度。
第三行包含n個正整數f_1,f_2,…,f_n(1<=f_i < c_i),分別表示每個橫座標對應的下邊界的高度。
Output
輸出一行一個整數,即最少的能量,若無法到達終點,請輸出“-1”。
Sample Input
4
3 4 3 2
1 2 1 1
Sample Output
4
HINT
“在左右移動的時候,太空貓【可以】下降到對應重力方向更低的位置”
應改爲 “太空貓【會】下降到對應重力方向更低的位置”
就是說,太空貓在能往下掉的時候不能選擇直接飛過去
Source
鳴謝Claris上傳試題
[Submit][Status][Discuss]
記
f[i][0/1] 爲到達第i 列時處於上/下端點的最優方案
特判掉無解,轉移方程顯然
(我可能在刷水麼。。。???)
#include<iostream>
#include<cstdio>
#define min(a,b) ((a) < (b) ? (a) : (b))
using namespace std;
const int maxn = 1E5 + 10;
typedef long long LL;
const LL INF = 1E16;
int n;
LL u[maxn],d[maxn],g[maxn],f[maxn][2];
inline int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret * 10 + ch - '0',ch = getchar();
return ret;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
n = getint();
for (int i = 1; i <= n; i++) u[i] = getint();
for (int i = 1; i <= n; i++) d[i] = getint(),g[i] = u[i] - d[i];
for (int i = 2; i <= n; i++)
{
if (u[i - 1] > u[i] && d[i - 1] < d[i]) {puts("-1"); return 0;}
if (u[i] <= d[i - 1] || d[i] >= u[i - 1]) {puts("-1"); return 0;}
}
f[1][1] = INF;
for (int i = 2; i <= n; i++)
{
f[i][0] = f[i][1] = INF;
if (f[i - 1][0] != INF)
{
if (d[i - 1] >= d[i]) f[i][0] = min(f[i][0],f[i - 1][0]);
if (u[i - 1] <= u[i]) f[i][1] = min(f[i][1],f[i - 1][0] + g[i - 1]);
}
if (f[i - 1][1] != INF)
{
if (u[i - 1] <= u[i]) f[i][1] = min(f[i][1],f[i - 1][1]);
if (d[i - 1] >= d[i]) f[i][0] = min(f[i][0],f[i - 1][1] + g[i - 1]);
}
}
cout << min(f[n][0],f[n][1] + g[n]) << endl;
return 0;
}