状压DP-售货员的难题

售货员的难题

题解:
这是一个状压DP还是很好想的,n个村庄就有 2 n 2^n 种可能,n=20所以我们直接暴力枚举就可以了。我们直接枚举当前到了,因为二进制的关系所以我们村庄从0-n-1更好做一些。我们先枚举一个I村庄在S状态中,再,枚举一个j村庄不在这个状态中,所以到达j村庄过后我们的状态就变成了S异或j村庄的新状态。

我们dp[i][j]的含义就是最后一个到达i村庄并且状态是j的所用路程。最后因为我们每个村庄都有可能是最后一个村庄,所以我们取一个最小值就可以了。

#include<bits/stdc++.h>
using namespace std;
const int N=20;
int n,dp[N][1<<N],g[N][N],res;
int main()
{
	int n; cin>>n;
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>g[i][j];
	memset(dp,0x3f3f3f3f,sizeof dp);
	dp[0][1]=0;
	for(int i=0;i<1<<n;i++){
		for(int j=0;j<n;j++){
			if(1<<j&i){
				for(int k=0;k<n;k++){
					if(!(1<<k&i)){
						dp[k][(1<<k)|i]=min(dp[k][(1<<k)|i],dp[j][i]+g[j][k]);
					}
				}
			}
		}
	}
	int res=0x3f3f3f3f;
	for(int i=0;i<n;i++){
		res=min(res,dp[i][(1<<n)-1]+g[i][0]);
	}
	cout<<res<<endl;
}
发布了92 篇原创文章 · 获赞 6 · 访问量 1167

猜你喜欢

转载自blog.csdn.net/weixin_42979819/article/details/103939481