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

一开始回溯法显然超时
然后加了一个剪枝勉强能过
不过花了800+ms
#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define N
int n;
struct node
{
    double x,y;
}s[20];
int vis[20];
double dd(node a,node b )
{
  return sqrt( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) );
}
double mind=inf;

void dfs(int cur,int cnt,double d)
{
   if(cnt==n)
   {
       mind=min(mind,d);
       return ;
   }
   if(d>=mind)return ;//关键剪枝
    rep(i,1,n)
    {
        if(vis[i])continue;
        vis[i]=1;
        dfs(i,cnt+1,d+dd( s[cur],s[i] ));
        vis[i]=0;
    }
    return ;
}
int main()
{
    RI(n);
    rep(i,1,n)
    cin>>s[i].x>>s[i].y;
    
    rep(i,1,n)
    vis[i]=1,dfs(i,1,sqrt(s[i].x*s[i].x+s[i].y*s[i].y) ),vis[i]=0;
    
    printf("%.2lf",mind);
    return 0;
}
View Code

按照曼哈顿距离排序的话剪了30ms。。。


n<=15的回溯法就接近爆时间









猜你喜欢

转载自www.cnblogs.com/bxd123/p/10662026.html