90 平台上求助(写了注释)
查看原帖
90 平台上求助(写了注释)
482347
ZZQF5677楼主2024/2/26 15:23
// ZZQF5677
#include <bits/stdc++.h>
using namespace std;
int n, D;
double ans;
const int INF = 0x7f7f7f;
double dist(double x11, double y11, double x22, double y22) {
	double op = sqrt(abs(x11 - x22) * abs(x11 - x22) + abs(y11 - y22) * abs(y11 - y22));
	if (op > D) {
		return INF;
	}
	return op;
}
double d[25][25]; // 两点间的最短路。
 
int x[25], y[25];

double dp[1048577][25]; // 走到第几个点。 

// 第几次(压缩)走到 j 点,走了的情况是 k,数组值是最小值,经过了相同的点,反正都走到了这个点,那肯定要最小的走法,不影响这个点下次向谁递归。。。

bool now = 0;
bool last = 1; 

int h[25]; // 预处理每个点到哪一个点距离最近。 
int main() {
	//freopen("1.in", "r", stdin);
	cin >> n >> D;
	const int nn = n;
	for (int i = 1; i <= n; i++) {
		cin >> x[i] >> y[i];
	}	
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			d[i][j] = dist(x[i], y[i], x[j], y[j]);
			if (d[i][j] > D) { // 一定要注意是单次飞行不超过 D!!! 
				d[i][j] = INF;
			}
		}
	}
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
			}
		}
	}
	/*
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			
		}
	}
	*/
	/// 
	/*
	一个点的状态从另一点 0 比自己少(或者等于)的状态进行转移,另一点的数值肯定比自己小(或者等于)
	*/
	memset(dp, INF, sizeof(dp));
	dp[0][0] = 0;
	dp[1][1] = 0;
	for (int k = 0; k <= (1 << n) - 1; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				// 我们记 k 为原状态(j)的,现在要转移到 i。
				// i 号点 0 -> 1。 
				if ((k & (1 << (j - 1))) && !(k & (1 << (i - 1)))) {
					dp[k | (1 << (i - 1))][i] = min(dp[k | (1 << (i - 1))][i], dp[k][j] + dist(x[i], y[i], x[j], y[j]));
				}
				// j 走到 i 号点,i 状态还是 1。 
				if ((k & (1 << (j - 1))) && (k & (1 << (i - 1)))) {
					dp[k][i] = min(dp[k][i], dp[k][j] + dist(x[i], y[i], x[j], y[j]));
				}
				// dp[k | (1 << (i - 1))][i] = min(dp[k | (1 << (i - 1))][i], dp[k | (1 << (j - 1))][]);	 
			}
			
		}
	}
	/*
	cout << dp[3][2] << "\n";
	cout << dp[7][3] << "\n";
	cout << dp[15][4] << "\n";
	*/
	ans = INF;
	const int END = (1 << n) - 1;
	for (int i = 1; i <= n; i++) {
		ans = min(ans, dp[END][i] + d[i][1]);
	}
	cout << fixed << setprecision(2) << (ans + 0.00) << "\n"; 
	return 0;
}

谢谢!!!

2024/2/26 15:23
加载中...