样例没过,请问状态转移中有无错误,求调
查看原帖
样例没过,请问状态转移中有无错误,求调
918894
XyGetItRightAker楼主2023/10/28 10:59
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#define inf 1e9
using namespace std;
int n, D;
int x[21], y[21];
double G[21][21];
double f[1 << 21][21];//下标表示飞行到的村庄,存的是距离
int read();

int main() {
	n = read(), D = read();
	for (int i = 1; i <= n; i++) {
		x[i] = read(), y[i] = read();
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (i == j)continue;
			G[i][j] = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
			if (G[i][j] > D) {
				G[i][j] = inf;
			}
		}
	}
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
			}
		}
	}
	memset(f, 0x7f, sizeof(f));
	f[1][0] = 0;

	for (int i = 1; i < 1 << n; i++) {//遍历每种状态
		//比如 1 1 1 0 0 1 1 1
		for (int j = 0; j < n; j++) {//遍历从哪里转移来的
			if ((1 << j) & i) {//如果能从这里转移来
				//比如1 1 1 0 0 1 1 0      1 1 1 0 0 1 0 1    .....
				for (int k = 1; k <=n; k++)//遍历从这里转移的上一个到的点是谁
				{
					if (1 << k - 1 & i-(1<<j))//如果能从这里转移
						//
						// 
						// 我不管你的上一个是谁第一个还是第几个,我要最小的
						// 
						//
						f[i][j + 1] = min(f[i][j + 1], f[i-(1 << j)][k] + G[k][j + 1]);//
				}
			}
		}
	}
	double ans=1e9;
	for (int i = 1; i <= n; i++) {
		ans = ans>f[(1 << n ) - 1][i]? f[(1 << n ) - 1][i]:ans;
	}


	printf("%0.2lf", ans);
	return 0;
}

int read() {
	char ch = getchar();
	int res = 0;
	while (ch >= '9' || ch <= '0') {
		ch = getchar();
	}
	while (ch <= '9' && ch >= '0') {
		res = res * 10 + ch - '0';
		ch = getchar();
	}
	return res;
}
// 1 1 1 1
// 
// 1 1 1 1 1 1 1 1
// 0 1 1 1 1 1 1 1 
// 
//
2023/10/28 10:59
加载中...