AT_abc180_e [ABC180E] Traveling Salesman among Aerial Cities 题解
分析
\(1 \le N \le 17\),一眼状压。
定义 \(f_{s,i}\) 表示从 \(1\) 走到 \(i\),且经过点的状态为 \(s\) 的最小代价。不难推出转移方程:\(f_{s+2^{j-1},j}=\min(f_{s,i}+val_{i,j})\)。其中 \(val_{i,j}\) 表示从 \(i\) 走到 \(j\) 的代价。由于我们在最后还需要回到 \(1\),所以答案就是 \(\min\{f_{2^n-1,i}+val_{i,1}|1 \le i \le n\}\)。
复杂度 \(O(2^nn^2)\)。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
const int N=18,M=1<<18;
int n;
int x[N],y[N],z[N];
int f[M][N];
int Min=1e18;
il void solve(){
memset(f,0x3f,sizeof(f)),f[1][1]=0;
cin>>n;
for(re int i=1;i<=n;++i)
cin>>x[i]>>y[i]>>z[i];
for(re int i=1;i<(1<<(n));++i)
for(re int now=1;now<=n;++now)
if((i>>(now-1))&1)
for(re int j=1;j<=n;++j)
if(!((i>>(j-1))&1))
f[i+(1<<(j-1))][j]=min(f[i+(1<<(j-1))][j],f[i][now]+(abs(x[j]-x[now])+abs(y[j]-y[now])+max(0LL,z[j]-z[now])));
for(re int i=1;i<=n;++i)
Min=min(Min,f[(1<<n)-1][i]+(abs(x[1]-x[i])+abs(y[1]-y[i])+max(0LL,z[1]-z[i])));
cout<<Min;
return ;
}
signed main(){
solve();
return 0;
}

浙公网安备 33010602011771号