题目描述
房间里放着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:
复制
View Code
View Code
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; }
按照曼哈顿距离排序的话剪了30ms。。。
n<=15的回溯法就接近爆时间
加上一个剪枝可以进行一定程度的优化
预处理两点距离即可
580ms
#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; double dis[20][20]; 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+dis[cur][i]); vis[i]=0; } return ; } int main() { RI(n); rep(i,1,n) cin>>s[i].x>>s[i].y; rep(i,1,n) rep(j,1,n) dis[i][j]=dd(s[i],s[j]); 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; }