可以参考这道题:91. 最短Hamilton路径 - AcWing题库
思路:
- dp[i][j],i表示的是状态,可以用二进制来表示某一个地方是否去过,例如10001,就代表去过了第一个和最后一个城市,j表示整个旅途以j(第j+1个城市)为终点。最短Hamilton路径是求从0到n-1的最短路径,毕业旅行问题可以套用最短Hamilton路,求出从0到1~n-1的最短路径,在加上各个点到0的路径长度,并取最小值。
- 状态转移方程是dp[i][j]=max(dp[i-某一个位置状态][k]+a[k][j])
- 数组初始化:dp[1][0]=0,也就是只去过北京,出发点还在北京,所以路径为0。
C++代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int a[21][21];
vector<vector<int>> dp(1<<20,vector<int>(20,0x3f3f3f3f));
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
dp[1][0]=0;
/*dp*///i--遍历状态,j--遍历起点
for(int i=1;i<(1<<n);i+=2){//跳过所有偶数
for(int j=0;j<n;j++){
if(i>>j&1){
for(int k=0;k<n;k++){
if((i-(1<<j))>>k&1){
dp[i][j]=min(dp[i][j],dp[i-(1<<j)][k]+a[k][j]);
}
}
}
}
}
int res=0x3f3f3f3f;
for(int i=1;i<n;i++){
res=min(res,dp[(1<<n)-1][i]+a[i][0]);
}
cout<<res;
return 0;
}
Python代码:
n=int(input())
a=[]
dp=[[0x3f3f3f3f for _ in range(20)] for _ in range(1<<20)]
for i in range(n):
temp=list(map(int,input().split()))
a.append(temp)
dp[1][0]=0
i=1
while i<(1<<n):
for j in range(n):
if i>>j&1:
for k in range(n):
if (i-(1<<j))>>k&1:
dp[i][j]=min(dp[i][j],dp[i-(1<<j)][k]+a[k][j])
i+=2
res=0x3f3f3f3f
for i in range(1,n):
res=min(res,dp[(1<<n)-1][i]+a[i][0])
print(res)
注意a的输入:
#二维数组的输入
a=[]
for i in range(n):
temp=list(map(int,input().split()))
a.append(temp)