P1433 吃奶酪

状态压缩模板题目
链接:https://www.luogu.com.cn/problem/P1433
说明:
dp[s][j]表示的是含有j号点s集合,以j号点为终点的最小旅行商距离!
那么dp[s][j] = min(dp[s][j],dp[s^(1<<j)][k] + dist(j,k));
其中:dp[s^(1<<j)][k]指的是去掉s中的j号点,并且以k为终点的距离
记忆并理解

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;





struct point
{
	double x, y;
}pointlst[20];
double dist(point x, point y) { return sqrt((double)pow(x.x - y.x, 2) + (double)pow(x.y - y.y, 2)); }
double dp[1 << 17][17];

int n;
int main()
{
	for (int i = 0; i < (1 << 17); i++)for (int j = 0; j < 17; j++)dp[i][j] = 0x3f3f3f;
	cin >> n;
	for (int i = 1; i <= n; i++)cin >> pointlst[i].x >> pointlst[i].y;
	dp[1][0] = 0;
	pointlst[0].x = pointlst[0].y = 0;
	n++;
	for (int s = 1; s < (1 << n); s++)
		for (int j = 0; j < n; j++)
			if ((s >> j) & 1)//如果s有j号点
				for (int k = 0; k < n; k++)
					if ((s ^ (1 << j)) >> k & 1)//如果s去掉j号点,还有k号点。
						dp[s][j] = min(dp[s][j], dp[s^(1<<j)][k] + dist(pointlst[k], pointlst[j]));
	double mini = 0x3f3f3f;
	for (int i = 1; i < n; i++)
		mini = min(mini, dp[(1 << n) - 1][i]);
	printf("%.2f", mini);
	return 0;
}

OwO!

posted on 2024-04-07 21:09  WHUStar  阅读(3)  评论(0编辑  收藏  举报