首先我们来看看这样一个问题,即著名的最优配对问题
对于空间里有n个点,给定n个点间的距离,将n个点两两配成n/2对,使得所有点对距离之和最小(n<=20)。
对于这样一个问题,我们可以知道这是一个多决策的问题,首先为第1个点作决策进行配对,然后为第2个点进行配对,因此每一个阶段的状态必然包含当前有哪些点参与配对,哪些点未参与配对,而如果将不确定个数和序号的点保存下来呢?答案是集合,我们可以利用二进制的方法,利用二进制法对集合进行表示,第i位为1则表示第i个点参与配对。
于是不难想到用dp[S]表示集合S里的点两两最优配对后的最小距离和,那么dp[S]为S里序号最小的元素与集合S里其他任意元素j匹配后的最小值
即状态转移方程为dp[S]=min(dp[S],dp[S^(1<<i)^(1<<j)]+dist[i][j]);
for(int S=0;S<(1<<n);S++)
{
int i,j;
dp[S]=0x3f3f3f3f;
for(i=0;i<n;i++)
if((1<<i) & S)
break;
for(j=0;j<n;j++)
{
if((1<<j) & S)
dp[S]=min(dp[S],dp[S^(1<<i)^(1<<j)]+dist[i][j]);
}
}