【回溯】B055_LQ_郵局(暴搜 / dp?)

一、Problem

C村住着n戶村民,由於交通閉塞,C村的村民只能通過信件與外界交流。爲了方便村民們發信,C村打算在C村建設k個郵局,這樣每戶村民可以去離自己家最近的郵局發信。

現在給出了m個備選的郵局,請從中選出k個來,使得村民到自己家最近的郵局的距離和最小。其中兩點之間的距離定義爲兩點之間的直線距離。

輸入格式

輸入的第一行包含三個整數n, m, k,分別表示村民的戶數、備選的郵局數和要建的郵局數。

接下來n行,每行兩個整數x, y,依次表示每戶村民家的座標。

接下來m行,每行包含兩個整數x, y,依次表示每個備選郵局的座標。

在輸入中,村民和村民、村民和郵局、郵局和郵局的座標可能相同,但你應把它們看成不同的村民或郵局。

輸出格式

輸出一行,包含k個整數,從小到大依次表示你選擇的備選郵局編號。(備選郵局按輸入順序由1到m編號)

樣例輸入
5 4 2
0 0
2 0
3 1
3 3
1 1
0 1
1 0
2 1
3 2
樣例輸出
2 4

數據規模和約定

對於 30%30\% 的數據,1<=n<=101<=m<=101<=k<=51<=n<=10,1<=m<=10,1<=k<=5
對於 60%60\% 的數據,1<=m<=201<=m<=20
對於 100%100\% 的數據,1<=n<=501<=m<=251<=k<=101<=n<=50,1<=m<=25,1<=k<=10

二、Solution

題意:從 m 個郵局中選 k 個,使得每戶村民到這 k 個郵局中距離最近的郵局的距離總和最小…

方法一:dfs + 枚舉(超時)

  • 定義 Pos 類存儲村民和郵局的座標…
  • dfs 從 m 個郵局選取 k 後,立即判斷每戶村民到這 k 個郵局的距離總和…
  • 取其中可構成每戶村民距離總和最小的 k 個郵局的編號…

40/100

可以優化一下:預處理一下每個村民到最近的郵局的距離到數組中…

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		int N, M, K;
		int INF = 0x3f3f3f3f, MIN;
		Pos[] hm;
		Pos[] stp;
		int[] res, tmp;
		
		int mini(int id) {
			int min = INF;
			for (int i = 0; i < K; i++) {
				int sID = tmp[i];
				int a = hm[id].x-stp[sID].x;
				int b = hm[id].y-stp[sID].y;
				min = Math.min(min, (int)Math.sqrt(a*a + b*b));
			}
			return min;
		}
		void dfs(int c) {
			if (c == K) {
				int sum = 0;
				for (int i = 0; i < N; i++)
					sum += mini(i);
				if (sum < MIN) {
				    MIN = sum;
    				res = Arrays.copyOf(tmp, tmp.length-1);
				}
				return;
			}
			for (int i = c; i < M; i++) {
				tmp[c] = i;
				dfs(c+1);
			}
		}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			N = sc.nextInt();
			M = sc.nextInt();
			K = sc.nextInt();
			hm = new Pos[N];
			stp = new Pos[N];
			
			for (int i = 0; i < N; i++) {
				int a = sc.nextInt(), b = sc.nextInt();
				hm[i] = new Pos(a, b);
			}
			for (int i = 0; i < M; i++) {
				int a = sc.nextInt(), b = sc.nextInt();
				stp[i] = new Pos(a, b);
			}
			res = new int[K+5];
			tmp = new int[K+5];
			MIN = INF;
			dfs(0);
			System.out.print(res[0]+1);
			for (int i = 1; i < K; i++)
				System.out.printf(" %d",res[i]+1);
		}
		class Pos {
			int x, y;
			Pos(int x, int y) {this.x = x;this.y = y;}
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

複雜度分析

  • 時間複雜度:O(2m)O(2^m)
  • 空間複雜度:O(...)O(...)

方法二:dp

代辦…

複雜度分析

  • 時間複雜度:O()O()
  • 空間複雜度:O()O()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章