传送门
感觉是一道经典的状压dp,随便写了一发卡了卡常数开了个
O(2)
O
(
2
)
优化水过。。。
我直接用
dp[i][j]
d
p
[
i
]
[
j
]
表示当前在第i个点,现在点的选取状况是j(二进制表示状态)。
这样的话直接位运算枚举出可以前去的点,然后转移状态。边界是所有点都被取过一遍。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int dp[21][1050000],dis[25][25],n;
inline int min(int a,int b){return a<b?a:b;}
inline int dfs(int p,int state){
if(dp[p][state]!=0x3f3f3f3f)return dp[p][state];
if(state==(1<<n)-1)return dp[p][state]=dis[p][1];
for(int i=1;i<=n;++i)if(((1<<(i-1))&state)==0)dp[p][state]=min(dp[p][state],dis[p][i]+dfs(i,state|(1<<(i-1))));
return dp[p][state];
}
int main(){
memset(dp,0x3f,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
scanf("%d",&dis[i][j]);
printf("%d",dfs(1,1));
return 0;
}