https://acm.uestc.edu.cn/problem/oyhuan-you-shi-jie/description
状压dp
由n=17可以知道是状压dp,然后推出转移方程
dp[now][st] 为当前以now结尾且状态为st
故 dp[i][st|1<<(i-1)] = min(dp[i][st|1<<(i-1)],dp[now][st]+dis[now,i]);
然后进行深搜
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 2e5+9;
int nx[30],ny[30];
ll dp[30][maxn];
int n;
int dis(int i,int j){
return abs(nx[i]-nx[j])+abs(ny[i]-ny[j]);
}
void dfs(int s,int st){
for(int i=1;i<=n;i++){
if(!(st&(1<<(i-1)))){
// cout<<655<<endl;
if(dp[i][st|(1<<(i-1))]>dp[s][st]+dis(s,i)){
// cout<<dp[s][st]+dis(s,i)<<endl;
dp[i][st|(1<<(i-1))]=dp[s][st]+dis(s,i);
dfs(i,st|(1<<(i-1)));
}
}
}
}
int main(){
int s;
scanf("%d%d",&n,&s);
for(int i=1;i<=n;i++){
scanf("%d%d",&nx[i],&ny[i]);
}
memset(dp,0x3f,sizeof(dp));
dp[s][1<<(s-1)]=0;
dfs(s,1<<(s-1));
ll Max = INF;
// for(int i=1;i<=n;i++){
// for(int j=1;j<1<<n;j++){
// cout<<dp[i][j]<<" ";
// }
// cout<<endl;
// }
for(int i=1;i<=n;i++){
Max=min(Max,dp[i][(1<<n)-1]);
}
printf("%lld\n",Max);
return 0;
}