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!