https://www.luogu.org/problemnew/show/P1433
题目描述
房间里放着n块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处。
输入输出格式
输入格式:
第一行一个数n (n<=15)
接下来每行2个实数,表示第i块奶酪的坐标。
两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
输出格式:
一个数,表示要跑的最少距离,保留2位小数。
输入输出样例
输入样例#1: 复制
4
1 1
1 -1
-1 1
-1 -1
输出样例#1: 复制
7.41
思路:提前预处理出来第i个点到第j个点的距离。(只需要记录奶酪之间的距离以及奶酪到起点的距离就好了)然后就可以开始dfs了,注意剪枝优化一下。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
double x[20];
double y[20];
int vis[20];
double len[20][20]; //len[i][j] 记录x[i]y[i] 与x[j]y[j]之间的距离
int n;
double MIN=0x3f3f3f3f;
void dfs(int cur,int i,double length);
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>x[i]>>y[i];
x[0]=y[0]=0; //起点
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
len[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
vis[0]=1; //标记起点
dfs(0,0,0.0);
printf("%.2f",MIN);
return 0;
}
void dfs(int cur,int i,double length)
{
if(length>MIN)
return; //剪枝
if(cur==n)
{
MIN=min(MIN,length);
return ;
}
for(int j=1;j<=n;j++)
{
if(!vis[j]) //没有经过的点
{
vis[j]=1;
dfs(cur+1,j,length+len[i][j]);
vis[j]=0;
}
}
}