吃奶酪这道题,本来数据很小,但由于洛谷管理员大大的加强,
成功地卡掉了题解排名第一的DFS做法。
呵呵呵说好的裸搜索题,搜索做法被卡掉了是几个意思?
我也是在写了一个DFS发现被卡之后来翻题解,
然后发现排名第一的题解做法不是和我一模一样吗?
copy下来放下本地跑10的数据,
发现跑了8秒。。。
才发现貌似是题解的问题。
下次麻烦管理员大大更毒瘤数据时,更新一下题解好不?
然后翻了翻题解,发现都是时间都很远古,
也就是说所有的dfs做法貌似都跑不过。。。
那请问为何要放在搜索的题单里,
而不是dp里?
不过我堂堂天朝OIer,怎可放弃DFS爆搜?
于是本人苦心研究,终于做出了启发式搜索的做法。
注意:
启发式搜索并非正解,
因为数据
毒瘤,
那我们做题人就得
更毒瘤!
充分发挥我天朝OIer面向数据编程的传统美德,
可以用memory(顾名思义)的一个二维数组存储
第一位表示点i,第二维表示步数step,
存储什么呢?
存储最短的距离,
如果后来访问到这个点,
就将当前已经走的距离同这个数组里存储的最短距离进行比较,
如果小于就更新,大于就return
我们发现,这是记忆化+贪心思想,
但是这个记忆化贪心并非是对的,
以为每一步的抉择具有后效性,
也许你走step步到i点的最短距离是正确的,
但并不能保证走step+1步到i+1(也可以是其他点)的最短路径就是memory[i][step]+distance[i][i+1]
那怎么办呢?(此时教练可能会提醒你用动态规划了,转dp正解)
但我就是想用DFS怎么办呢?
那就该请出我们今天的主角了——启发式搜索,
简单来说,启发式搜索就是对取和不取都做分析,从中选取更优解(或删去无效解)
代码的关键就是这么一行:
if(s<memory[i][step]+s2)
{
memory[i][step]=s;
}
这里的s2取什么呢?
因为我谷可下载未通过测试的数据点,
故经过一番思考(胡搞)后
可发现s2取sqrt(0.8)可通过所有测试点
(s2的取值视情况而定,追求速度可以往小取。追求稳妥可以往大取)
并且整个程序跑得飞快——53ms
甚至超越了dp正解的171ms
我拒绝和数据改造之前的记录对比
奉上AC代码
#include<bits/stdc++.h>
using namespace std;
int N;
struct pue
{
double a,b;
};
pue w[22];
double ans=INT_MAX;
double distance[30][35];
double memory[30][30];
bool vis[25];
double s2=sqrt(0.8);
double calculate(double x1,double y1,double x2,double y2)
{
double ke=x1-x2,kr=y1-y2;
return sqrt(ke*ke+kr*kr);
}
void yuchuli()
{
for(int i=0;i<=N;i++)
for(int j=0;j<=N;j++)
{
memory[i][j]=INT_MAX;
distance[i][j]=calculate(w[i].a,w[i].b,w[j].a,w[j].b);
}
}
void dfs(double s,int i,int step)
{
if(s<memory[i][step]+s2)
{
memory[i][step]=s;
}
else
return ;
if(step==N)
{
if(ans>s)ans=s;
return ;
}
for(int j=1;j<=N;j++)
{
if(i==j)continue;
if(vis[j]==0)
{
double k=s+distance[i][j];
if(k<ans)
{
vis[j]=1;
dfs(k,j,step+1);
vis[j]=0;
}
}
}
}
bool com(pue x,pue y)
{
if(x.a!=y.a)return x.a>y.a;
else
return x.b>y.b;
}
int main()
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%lf%lf",&w[i].a,&w[i].b);
}
sort(w+1,w+1+N,com);//这里需要从大到小进行排序
yuchuli();
dfs(0.0,0,0);
printf("%.2f",ans);
return 0;
}
再次重申,这不是正解!!!
正确性完全经由数据范围而定,
出题人只要换一下大数据,也许就能卡掉,
(不过可以试试s2取其它数)
只是觉得既然是个搜索题,就一定要有搜索的解法,不然怎么对得起题目呢?
同时,也告诉大家,有时使用启发式搜索在考场上打深搜暴力有奇效。
希望大家能有所收获。
如果觉得作者写的还行,就点个赞吧!