程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> uva 1474 - Evacuation Plan(dp)

uva 1474 - Evacuation Plan(dp)

編輯:C++入門知識

題目連接:uva 1474 - Evacuation Plan


題目大意:給出n,表示有個施工隊,然後給出n個施工隊的位置;然後給出m,表示說有m個避難所,接著給出m個避難所得位置,現在要將每個施工隊分配給避難所,要求移動的總距離最小,並且沒有避難所空閒。


解題思路:dp[i][j]表示說i個施工隊使用j個避難所得最短距離,將施工隊和避難所的距離從小到大排序後,選取避難所就可以采取就近原則,path[i][j]用來記錄路徑,dp數組可以用滾動數組優化空間。


#include 
#include 
#include 
#include 

using namespace std;
typedef long long ll;
const int N = 4005;
const ll INF = 1e17;

struct team {
	int d, id;
} s[N], p[N];

int n, m, path[N][N], ans[N];
ll dp[2][N];

bool cmp(const team& a, const team& b) {
	if (a.d != b.d) return a.d < b.d;
	return a.id < b.id;
}

void init () {
	for (int i = 1; i <= n; i++) {
		scanf("%d", &s[i].d);
		s[i].id = i;
	}

	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d", &p[i].d);
		p[i].id = i;
	}

	sort(s+1, s+n+1, cmp);
	sort(p+1, p+m+1, cmp);
}

ll solve () {
	for (int i = 1; i <= m; i++) dp[0][i] = INF;
	dp[0][0] = 0;
	
	for (int i = 1; i <= n; i++) {
		int u = i%2;
		int v = 1-u;
		for (int j = 0; j <= m; j++) dp[u][j] = INF;

		for (int j = 1; j <= m && j <= i; j++) {
			if (dp[v][j-1] < dp[v][j]) {
				dp[u][j] = dp[v][j-1] + abs(s[i].d - p[j].d);
				path[i][j] = 1;
			} else {
				dp[u][j] = dp[v][j] + abs(s[i].d - p[j].d);
				path[i][j] = 0;
			}
		}
	}
	return dp[n%2][m];
}

void put(int x, int y) {
	if (x == 0 || y == 0) return;
	ans[s[x].id] = p[y].id;
	put(x-1, y-path[x][y]);
}

int main () {
	while (scanf("%d", &n) == 1) {
		init ();
		printf("%lld\n", solve ());
		put(n, m);
		for (int i = 1; i < n; i++) printf("%d ", ans[i]);
		printf("%d\n", ans[n]);
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved