題目: UVa - 10337 - Flight Planner
題目說明
在一個平面座標系上,有一架飛機從原點 ( 0, 0 )
起飛,要到 X
( X, 0 )
,將原點到 X
每 100 miles 分為一段,給每段的各個空層 ( 共 9 層 ) 的風速,飛機每飛過 100 miles 可以選擇往上一層、往下一層、或是平飛,花費的燃料依序為 60、20、30,且花費的燃料還要減掉該層的風速,求從起點到終點花費的最少燃料為何。飛機不能在地面平飛 ( 第 0 層 ),也不能飛超過第 9 層。
Input: 第一個整數 T
,表示有 T
組測資,每組測資第一個整數為 X
,後面 9 * X
/ 100 的表格為風速,以左下角為原點,向右為 x 軸 ( 0 ~ X
/ 100 ),向上為 y 軸 ( 0 ~ 9 )。
Output: 輸出從起點到終點的最小花費燃料。
解題思路
動態規劃題,先讀取測資,將每 100 miles 分為一段,winds[i][j]
表第 i
段,第 j
層的風速,先讀取風速,記得是從第 9 層開始。
定義 dp[i][j]
表飛機到達第 i
段,第 j
層所需的最小花費,對於 (i, j) 來說,只能從 (i - 1, j)、(i - 1, j - 1)、(i - 1, j + 1) 到達,依此想法做動態規劃即可,記得注意題目要求的一些限制,如不能在第 0 層走等等。
參考解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include <bits/stdc++.h>
using namespace std;
static auto __ = [] { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); return 0; }();
const int inf = (int)1e9;
int T; int X; int winds[1005][10]; int dp[1005][10];
void read() { cin >> X; X /= 100;
for (int i = 9; i >= 0; --i) for (int j = 0; j < X; ++j) cin >> winds[j][i], dp[j][i] = inf; }
void solve() { dp[0][0] = 0;
for (int i = 1; i <= X; ++i) for (int j = 0; j < 10; ++j) { int mn = INT_MAX; if (j > 0) { mn = min(dp[i - 1][j] + 30 - winds[i - 1][j], mn); mn = min(dp[i - 1][j - 1] + 60 - winds[i - 1][j - 1], mn); } if (j < 9) mn = min(dp[i - 1][j + 1] + 20 - winds[i - 1][j + 1], mn); dp[i][j] = mn; }
cout << dp[X][0] << "\n\n"; }
int main() { cin >> T; while (T--) { read(); solve(); } }
|
參考資料
[UVA] 10337 - Flight Planner | 水泥城式