[状压DP]P1433 吃奶酪 题解

状态压缩入门题。

状态很好想,记录一下结束的点与已经到达过的点就可以开始转移。

第一维存结束点,第二维存状态。

有一个小坑点就是不是任意点开始,而是要从 $ (0,0)$ 开始走,因此初始化的时候要赋一下初始值。(大概不会有人和我一样瞎

#include <bits/stdc++.h>
constexpr int N = 16;
using namespace std;
int n;
double ans , x[N] , y[N] , dis[N][N] , dp[N][1 << N];
int main() {
	ios :: sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	ans = 114514;
	memset(dp , 114514 , sizeof dp);
	cin >> n;
	for(register int i = 1; i <= n; ++i){
		cin >> x[i] >> y[i];
		dp[i][1 << i - 1] = __builtin_sqrt((x[i] * x[i]) + (y[i] * y[i]));
	}                    
	for(register int i = 1; i <= n; ++i) {
		for(register int j = 1; j <= n; ++j) {
			dis[i][j] = __builtin_sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));	
		}
	}
	for(register int i = 1; i < (1 << n); ++i) {
		for(register int j = 1; j <= n; ++j) {
			if(i & (1 << j - 1)) {
				for(register int k = 1; k <= n; ++k) {
					if(i & (1 << k - 1)) {
						dp[j][i] = min(dp[j][i] , dp[k][i ^ (1 << j - 1)] + dis[j][k]);
					}
				}
			}
		}
	}
	for(register int i = 1; i <= n; ++i){
		ans = min(ans , dp[i][(1 << n) - 1]);
	}
	cout << fixed << setprecision(2) << ans;
	return 0;
}
posted @ 2025-05-05 12:11  「癔症」  阅读(14)  评论(0)    收藏  举报