状压dp讲解

看一下模板题

搜索 O(n!) 不能接受。
我们设 dp 状态 dp_{i,j} 是当前在 j 这个点,走过的集合用二进制表示是 i
首先初始状态是 dp_{1,0}=0 因为它,固定了起始点是 0
然后走过的集合中 j 一定是要有的,要不然怎么可能走到 j ,这个可以用运算符判断 i\&(1<<j)
接着我们枚举下一个点,可以肯定这个点要在 i 中不出现,要不然都不用走,也不满足题意,判断方法和上面一样。
接下来就可以转移了先放式子 dp_{i+(1<<k),k}=min_{dp_{i+(1<<k),k}}^{dp_{i,j}+a_{j,k}}
之前的状态是 i 多了 k 之后就是 i+(1<<k) ,首先 dp 都是要和自己比的也就是 min 中的下面。
至于上面就是之前的状态加上路程。
最后的答案就是题目要求的,自己推。
最终复杂度 2^nn^2
核心代码:

for(int i=1;i<(1<<n);++i)
{
	for(int j=0;j<n;++j)
	if(i&(1<<j))
	{
		for(int k=1;k<n;++k)
		{
			if(i&(1<<k)) continue;
			dp[i+(1<<k)][k]=min(dp[i+(1<<k)][k],dp[i][j]+a[j][k]);
		}
	}
}

%%%%%%%%%%。

不用%
你也能会

%%%%%%%%%%。