0%

Acwing91题:最短Hamilton路径

主要还是dp的状态转移方程

拿一维作为走过哪些路,另一维表示现在站在哪个点上

然后再去枚举从哪个走过的点转移过来的

$dp[i][j]=min(dp[i][j],dp[i-(1<<j)][k]+a[k][j])$

需要注意的是初始状态,因为只能从0这个点转移过来,所以$dp[1][0]=0$

其他都需要被更新所以都赋值成正无穷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=21;

int a[maxn][maxn],dp[1<<maxn][maxn],n;

int main(){
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&a[i][j]);
memset(dp,0x3f,sizeof dp);
dp[1][0]=0;
for(int i=1;i<(1<<n);i++)
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]);
printf("%d\n",dp[(1<<n)-1][n-1]);
return 0;
}