通过dp位运算来解决
思路:
第一想到状态dp,用二进制位表示每个节点
那么(1<<n) -1表示全1情况也就是包含所有节点
dp[1<<n][n]
第一维表示走过0,1,2,3.。。。。n-1个点的所有情况
第二维表示最后一个点到达的的点
弄清楚这几点之后代码就很简单了
菜鸡的我想不到,只能看大佬的题解。。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 21;
int dp[1<<N][N];
int dist[N][N];
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n;
cin >> n;
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
cin >> dist[i][j];
}
}
memset(dp,0x3f3f3f,sizeof(dp));
dp[1][0] = 0;
for(int i = 0; i<(1<<n); i++){//遍历所有情况
for(int j = 0;j<n;j++){ //表示走过的上一个节点
if(i&(1<<j)){ //如果第j个节点走过就找下一个节点
for(int k = 0;k<n;k++){ //这表示下一步走的点
if(~(i>>k)&1)//找没走过的节点
dp[i+(1<<k)][k] = min(dp[i+(1<<k)][k],dp[i][j] + dist[j][k]);
}
}
}
}
cout << dp[(1<<n)-1][n-1] << endl;
return 0;
}