一开始分析暴力搜索最大复杂度是15!,于是想就是动态规划,但是本鞠弱不会压缩路径,放弃。突然想到如果记录了最短路径可以减少搜索的次数,抱着侥幸的心理提交代码,最后一个测试点还是超时了。
#include <cstdio>
#include <iostream>
#include <utility>
#include <cmath>
#include <iomanip>
using namespace std;
typedef struct Corrd
{
double dx = 0;
double dy = 0;
} Corrd;
double ans = 0x3f3f;
int n;
//假装动态规划,实际上只是记录路径长度
double dp[20][20] = {0};
int visited[20] = {0};
int solve(int status, int count, double sum)
{
//遍历完所有节点
if (count == n)
{
if (sum < ans)
{
ans = sum;
return 0;
}
}
for (int i = 1; i <= n; ++i)
{
//后面那个条件意思是如果路径已经太长了,就不往下了。起到一个剪枝的作用
if (!visited[i] && sum < ans)
{
visited[i]=1;
sum += dp[status][i];
solve(i, count + 1, sum);
//回溯
sum -= dp[status][i];
visited[i]=0;
}
}
return 0;
}
int main()
{
cin >> n;
Corrd corrd[20];
for (int i = 1; i <= n; ++i)
{
cin >> corrd[i].dx >> corrd[i].dy;
}
for (int i = 0; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
dp[i][j] = hypot(abs(corrd[i].dx - corrd[j].dx), abs(corrd[i].dy - corrd[j].dy));
}
}
// for (int i = 0; i <= n; ++i)
// {
// for (int j = 1; j <= n; ++j)
// {
// cout<<dp[i][j]<<endl;
// }
// }
solve(0, 0, 0);
printf("%.2lf",ans);
return 0;
}