P1433 吃奶酪
题目描述
房间里放着 nn 块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 (0,0)(0,0) 点处。
输入格式
第一行一个正整数 nn。
接下来每行 22 个实数,表示第i块奶酪的坐标。
两点之间的距离公式为 \sqrt{(x_1-x_2)^2+(y_1-y_2)^2}(x1−x2)2+(y1−y2)2
输出格式
一个数,表示要跑的最少距离,保留 22 位小数。
输入输出样例
4 1 1 1 -1 -1 1 -1 -1
7.41
说明/提示
1\leq n\leq 151≤n≤15。
此题是一道深搜题,用一个二进制记录走过的点,另一个记录老鼠所在的点。如果搜到的点比这点大,就停止搜索。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int n;
long double a[30][2],b[30][30],c[(1<<15)+15][18];//一维记录走过的点,二维记录现在的点。
long double c1,c2,s;
int d[30],i,j;
void h(int y,int t,int x,long double s1)//深搜
{
int i;
if(x==n+1)
{
if(s==0||s>s1)
{
s=s1;
return;
}
}
for(i=1;i<=n;i++)
{
if(d[i]==0)
{
int x1=t+(1<<(i-1));//记录当时所在的点。
if(c[x1][i]!=0)
{
if(c[x1][i]<=s1+b[y][i]))//如新的路径长度比之前的还长就不继续搜了。。
{
continue;
}
}
d[i]=1;
c[x1][i]=s1+b[y][i];
h(i,x1,x+1,c[x1][i]);
d[i]=0;//回溯
}
}
return ;
}
int main()
{
cin>>n;
a[0][0]=0;
a[0][1]=0;
for(i=1;i<=n;i++)
{
scanf("%Lf %Lf",&a[i][0],&a[i][1]);
for(j=0;j<i;j++)
{
c1=a[i][0]-a[j][0];
c2=a[i][1]-a[j][1];
b[j][i]=sqrt(c1*c1+c2*c2);
b[i][j]=b[j][i];
}
}
h(0,0,1,0);
printf("%.2Lf",s);
return 0;
}