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;
}

posted @ 2024-03-07 12:59  harmis_yz  阅读(18)  评论(0)    收藏  举报