洛谷 P1433 吃奶酪【DFS】+剪枝
题目链接: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位小数。
4
1 1
1 -1
-1 1
-1 -1
7.41 解题分析:
此题若用dfs来做的话,需要剪枝,不然必定超时,常规的有两种剪枝方法:
1.当搜索的距离大于此时保存的最小总距离的时候,这条dfs路线必然不符合要求,直接return,这个很关键。
2.搜索的时候不断求两点之间的距离非常耗时,所以我们可以在一开始就打好表,用dis[][]二维数组储存每两点之间的距离,然后后面搜索的时候直接调用就好了。(不过下面我的代码没有用到这个剪枝,也勉强AC了)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int n, res;double ans;
int vis[];
struct node
{
double x, y;
};
node arr[]; double dis(node a, node b)
{
double sum = ;
sum += sqrt((a.x - b.x)*(a.x - b.x)*1.0 + (a.y - b.y)*(a.y - b.y)*1.0);
return sum;
} void dfs(int ord,double distance) //当前点的序号 、总距离
{
if (distance >= ans)return; //如果距离大于等于现在的最小值,该dfs路线直接放弃,这个剪枝很重要
if (res == n&&distance<ans)
{
ans = distance; //更新最小值
}
for (int i = ; i <= n; i++)
{
if (!vis[i])
{
res++; vis[i] = ; //选这个点
dfs(i, distance + dis(arr[ord], arr[i]));
res--; vis[i] = ; //清空当前选择
}
}
} int main()
{
scanf("%d", &n);
for (int i = ; i <= n; i++)
{
scanf("%lf %lf", &arr[i].x, &arr[i].y);
}
arr[].x = ,arr[].y=;
ans = INF; res = ;
dfs(,);
printf("%.2lf\n", ans);
return ;
}
用了二维数组记录两点之间距离代码
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
#define INF 0x3f3f3f3f
int n,cur;
double ans; struct node
{
double x, y;
};
node arr[];
int vis[];
double map[][]; double dis(int i, int j)
{
return sqrt((arr[i].x-arr[j].x)*(arr[i].x - arr[j].x)+(arr[i].y-arr[j].y)*(arr[i].y - arr[j].y));
} void dfs(int ord,double sum)
{
if (sum >= ans)return;
if (cur == n)
{
ans = min(sum, ans);
}
else
{
for (int i = ; i <= n; i++)
{
if (!vis[i])
{
vis[i] = ; cur++;
dfs(i,sum +map[ord][i]);
vis[i] = ; cur--;
}
}
}
} int main()
{
cin >> n;
arr[].x = , arr[].y = ;
for (int i = ; i <= n; i++)
{
scanf("%lf %lf", &arr[i].x, &arr[i].y);
}
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
map[i][j] = dis(i, j); //开一个二维数组来记录任意两个点之间的距离,省的以后多次求(虽然对这道题来说并没有优化多少)
} //注意此时i-j的距离,还要记录j-i的距离,虽然这两个距离的值是一样的,但是遍历的时候,i有可能在j的前面,也有可能在j的后面,所以map[i][j]和map[j][i]都要记录
}
memset(vis, , sizeof(vis));
ans = INF,cur=;
dfs(,);
printf("%.2lf\n", ans);
return ;
}
2018-05-31
洛谷 P1433 吃奶酪【DFS】+剪枝的更多相关文章
- 洛谷 - P1433 - 吃奶酪 - dfs
https://www.luogu.org/problemnew/show/P1433 并不是每一个求最短距离就是bfs,这个肯定是dfs. 直接计算15!可以知道枚举必定超时,但是! 我们dfs非常 ...
- 洛谷P1433 吃奶酪【dfs】【剪枝】
题目:https://www.luogu.org/problemnew/show/P1433 题意: 给定n个坐标,要求从(0,0)开始走遍所有点,最少经过的路程. 思路: 刚开始想像数字三角形一样适 ...
- 洛谷 P1433 吃奶酪 Label:dfs && 剪枝Ex
题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块 ...
- 洛谷 P1433 吃奶酪(记忆化)
题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块 ...
- 集训作业 洛谷P1433 吃奶酪
嗯?这题竟然是个绿题. 这个题真的不难,不要被他的难度吓到,我们只是不会计算2点之间的距离,他还给出了公式,这个就有点…… 我们直接套公式去求出需要的值,然后普通的搜索就可以了. 这个题我用的深搜,因 ...
- 洛谷 P1433 吃奶酪
题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块 ...
- 洛谷P1433 吃奶酪 题解 状态压缩DP
题目链接:https://www.luogu.com.cn/problem/P1433 题目大意 房间里放着 \(n\) 块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 \((0, ...
- 洛谷P1433 吃奶酪
#include<iostream> #include<math.h> using namespace std ; ; int n; bool st[N]; double x[ ...
- 洛谷 P1433 吃奶酪 状压DP
题目描述 分析 比较简单的状压DP 我们设\(f[i][j]\)为当前的状态为\(i\)且当前所在的位置为\(j\)时走过的最小距离 因为老鼠的坐标为\((0,0)\),所以我们要预处理出\(f[1& ...
随机推荐
- POJ 1061 青蛙的约会 (扩展欧几里得算法)
题目链接 Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件 ...
- android aysncTask面试解析
- MySQL占用IO过高解决方案【转】
1.日志产生的性能影响: 由于日志的记录带来的直接性能损耗就是数据库系统中最为昂贵的IO资源.MySQL的日志包括错误日志(ErrorLog),更新日志(UpdateLog),二进制日志(Binlog ...
- 获取静态 selected的当前的value的值
<!DOCTYPE html><html><head><script>function checkField(val){alert("输入值已 ...
- ES系列目录
ES系列一.CentOS7安装ES 6.3.1 ES系列二.CentOS7安装ES head6.3.1 ES系列三.基本知识准备 ES系列四.ES6.3常用api之文档类api ES系列五.ES6.3 ...
- (并发编程)进程IPC,生产者消费者模型,守护进程补充
一.IPC(进程间通信)机制进程之间通信必须找到一种介质,该介质必须满足1.是所有进程共享的2.必须是内存空间附加:帮我们自动处理好锁的问题 a.from multiprocessing import ...
- 取消Eclipse控制台显示行数的限制
--------------------------------------------------------------------------------------------------- ...
- html中子界面与父界面相互操作或传值
一.在使用iframe的页面,要操作这个iframe里面的DOM元素可以用: contentWindow.contentDocument(测试的时候chrom浏览器,要在服务器环境下) content ...
- SQL定义变量
- java多线程快速入门(一)
1.什么是进程 比如:QQ.QQ游戏.eclipse都是进程,可以通过任务管理器查看进程 2.进程和线程区别 线程是进程的一部分,一个进程可以包含多个线程,一个线程只能属于一个进程 进程是所有线程的集 ...