4884: [Lydsy2017年5月月賽]太空貓

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;
}
發佈了730 篇原創文章 · 獲贊 20 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章