【グラフ理論】C_Counting Competition_On the Elevator(二次元抽象一次元)

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はエンドポイントです。
  • C [ ] C [i] もともとエレベーターが動くことを意味していました C C_i レイヤー、およびこのアルゴリズムでは、有向エッジのエッジの重みとして表現します。
  • 各制御スロット C [ ] C [i] は異なる有向エッジを表し、各フロアエレベーターは図のノードです。
  • エッジの重みが負になる可能性があるため、無限の周期的な動きが発生する可能性があります。
  • これまでのところ、この問題は、ポイント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;
		}
	}
}

複雑さの分析

  • 時間の複雑さ: k メートル O(キロ)
  • スペースの複雑さ: (...)

方法2:dp

充電器...


複雑さの分析

  • 時間の複雑さ: O()
  • スペースの複雑さ: O()
元の記事714件を公開 賞賛された199件 50,000件以上の表示

おすすめ

転載: blog.csdn.net/qq_43539599/article/details/105589208