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

 

 

这题有几个点要注意:

1.直接用dfs是会超时的,还要加入记忆化搜索和剪枝才行

2.对n==0时要特判

3.保留两位小数要记得,最好用printf比较方便

4.已经吃掉的奶酪要记录

5.要把老鼠一开始的位置也看成一个奶酪比较好理解

6.用于记录的数组一定要初始化

7.路程累加了以后一定要归位

讲一下思路:

很简单用dfs配合记忆化搜索和剪枝就能AC了

详细看代码和注释

上AC代码:

#include<iostream>//这个就不用解释了吧 
#include<cmath>//sqrt的头文件 
#include<cstring>//初始化函数 memset的头文件 
#include<cstdio>//用printf输出比较方便(详细看后面) 
double ans=1111111111;//存答案 
double now=0;//存现在的路程 
int n;//同题意 
bool book[20];//用于记录 
double ax[20];//存储奶酪的x轴的坐标 
double ay[20];//存储奶酪的y轴的坐标 
void dfs(int dq,int d);//dq代表 
double jl[20][20];//记忆化搜索的存储 
using namespace std;
int main(){
    memset(book,false,sizeof book);//初始化book 
    memset(jl,0,sizeof jl);//初始化jl 
    cin>>n;
    if(n==0){//对n等于0特判 
        cout<<0.00;
        return 0;//完美结束 
    }
    for(int i=1;i<=n;i+=1){//读入数据 
        cin>>ax[i];
        cin>>ay[i];
    }
    ax[0]=0;//初始化老鼠的坐标 
    ay[0]=0; 
    book[0]=true;//记录一开始的位置已经走过 
    dfs(0,0);//深搜开始 
    printf("%0.2lf",ans);//这就是用printf的好处:%0.2lf表示保留两位小数输出double型变量。 
    return 0;//完美结束 
}
void dfs(int dq,int d){
    if(now>ans)//这是剪枝,如果当前的路程大于答案就跳出 
    return;
    if(dq==n){//如果吃完了所有奶酪,就判断路程有没有小于答案 
        if(now<=ans){
            ans=now;
        }
        return;//跳出 
    }
    for(int i=1;i<=n;i+=1){//枚举所有的奶酪 
        if(book[i]==false){//如果没有被吃掉就从这个点再开始深搜 
            if(jl[d][i]!=0){//用到了记忆化搜索,这个奶酪到下一个奶酪如果之前又走过就把之前的值拿过来用 
                book[i]=true;//标记这个奶酪已经被吃掉 
                now+=jl[d][i];//路程累加 
                dfs(dq+1,i);//从这个点再开始深搜 
                book[i]=false;//归位 
                now-=jl[d][i];//归位
            }
            else if(jl[i][d]!=0){//同上面,只不过方向不一样 
                book[i]=true;
                now+=jl[i][d];
                dfs(dq+1,i);
                book[i]=false;
                now-=jl[i][d];
            }
            else{//如果没有走过就只能乖乖算了 
                book[i]=true;//标记这个奶酪已经被吃掉 
                jl[i][d]=sqrt((ax[i]-ax[d])*(ax[i]-ax[d])+(ay[i]-ay[d])*(ay[i]-ay[d]));//记录下来这个奶酪到下一个奶酪距离的值 
                now+=jl[i][d];//路程累加 
                dfs(dq+1,i);//从这个点再开始深搜 
                book[i]=false;//归位 
                now-=jl[i][d];//归位
            }
        }
    }
    return;//返回 
}

猜你喜欢

转载自blog.csdn.net/liangjiubujiu/article/details/83048199
今日推荐