售货员的难题
题解:
这是一个状压DP还是很好想的,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;
}