1.タイトルの説明
エレベーターの電源を入れた後、遠征隊員たちはエレベーターが走っている縦のトンネルに入り、塔の頂上に直接つながる線路、線路の下部に停まっているエレベーター、エレベーターのポールが見えたエレベーターを制御する巨大なハンドル。
ネスカフェタワーはN階で、エレベーターは各階に停車します。
ハンドルにはM個の制御スロットがあり、番号Ciはi番目の制御スロットの横にマークされ、C1 <C2 <C3 <... <CMを満たします。
Ci> 0の場合、ハンドルがこのスロットに移動すると、エレベーターはCiの床まで上昇します。Ci<0の場合、ハンドルがこのスロットに移動すると、エレベーターは-Ciの床まで下降し、Ci = 0、ハンドルが必要です。もともとこのスロットにありました。
エレベーターは1階とN階の間でしか移動できないため、制御スロットを引っ張ってエレベーターを1階の下およびN階の上に移動することはできません。
各エレベーターが1階移動するのに2秒かかり、ハンドルが1つの制御スロットから隣接するスロットに移動するのに1秒かかります。
探検隊のメンバーは現在レベル1にいるので、できるだけ早くレベルNに到達したいと考えています。レベル1からレベルNまでにどれくらいの時間がかかるか知りたいですか?
入力フォーマット
最初の行の2つの正の整数N、M。
2行目のM整数C1、C2 ... CM。
出力フォーマット
整数の出力は、答え、つまり少なくともどれだけ時間がかかるかを示します。
出力-1に到達できない場合。
データ範囲
1≤N≤1000、
2≤M≤20、
-N <C1 <C2 <... <CM <N
输入样例:
6 3
-1 0 2
输出样例:
19
サンプルの説明
ハンドルが2番目のスロットから3番目のスロット(0から2)に移動します。これには1秒かかり、エレベーターは4秒で3階まで上がります。
ハンドルは3番目のスロットでは動かず、エレベーターは4秒後に再び5階まで上がります。
ハンドルを最初のスロット(2から-1)に移動します。2秒かかります。エレベーターは4階まで下がり、2秒かかります。
ハンドルを3番目のスロットに移動し(-1は2を引き下げます)、2秒かかります。エレベーターは6階まで上がり、4秒かかります。
合計時間は(1 + 4)+4+(2 + 2)+(2 + 4)= 19秒です。
第二に、解決策
方法1:マップを調べる
一見、それはdpのように見えます。はい、dpを実行できます。比較的新しいアイデアは、問題をグラフ理論の最短問題に変えることです。
- ノード1はソースポイントで、nはエンドポイントです。
- もともとエレベーターが動くことを意味していました レイヤー、およびこのアルゴリズムでは、有向エッジのエッジの重みとして表現します。
- 各制御スロット は異なる有向エッジを表し、各フロアエレベーターは図のノードです。
- エッジの重みが負になる可能性があるため、無限の周期的な動きが発生する可能性があります。
- これまでのところ、この問題は、ポイント1からポイントnまでの最小時間を見つけるように簡略化できます。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static int n, m;
static int[] C;
static int[][] dist;
static int INF = 0x3f3f3f3f;
static void spfa(int S) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
dist[i][j] = INF;
}
Queue<Node> q = new ArrayDeque<>();
boolean[][] inq = new boolean[n+1][m+1];
q.add(new Node(1, S));
inq[1][S] = true;
dist[1][S] = 0;
while (!q.isEmpty()) {
Node t = q.poll();
int f = t.f, s = t.s;
inq[f][s] = false;
for (int i = 1; i <= m; i++) {
int tf = f + C[i];
if (tf < 1 || tf > n)
continue;
if (dist[tf][i] > dist[f][s] + Math.abs(f-tf)*2 + Math.abs(s-i)) {
dist[tf][i] = dist[f][s] + Math.abs(f-tf)*2 + Math.abs(s-i);
if (!inq[tf][i]) {
q.add(new Node(tf, i));
inq[tf][i] = true;
}
}
}
}
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(System.out));
n = sc.nextInt();
m = sc.nextInt();
C = new int[m+1];
int start = 0;
for (int i = 1; i <= m; i++) {
C[i] = sc.nextInt();
if (C[i] == 0)
start = i;
}
int min = INF;
dist = new int[n+1][m+1];
spfa(start);
for (int i = 1; i <= m; i++) {
min = Math.min(min, dist[n][i]);
}
System.out.println(min == INF ? -1 : min);
}
static class Node {
int f, s;
Node(int f, int s) {
this.f = f;
this.s = s;
}
}
}
複雑さの分析
- 時間の複雑さ: 、
- スペースの複雑さ: 、
方法2:dp
充電器...
複雑さの分析
- 時間の複雑さ: 、
- スペースの複雑さ: 、