TSP问题的状态DP解法:
题意:从1点开始遍历全图的点后回到起点的最短路径问题
因为TSP不限制每个点遍历的次数,所以可以用floyd处理下两点间的距离,之后DP处理下,
DP[i][j]表示状态为二进制i下,当前遍历第j个点的最小值,DP[1<<j][j]初始化为map[0][j]
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
const int maxn=12;
const int maxm=1<<11|1;
int n;
int map[maxn][maxn];
int dp[maxm][maxn];
void floyd()
{
for (int k=0 ; k<=n ; ++k)
for (int i=0 ; i<=n ; ++i)
for (int j=0 ; j<=n ; ++j)
if(map[i][j]>map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
}
int main ()
{
while (~scanf("%d",&n)&&n)
{
for (int i=0 ; i<=n ; ++i)
for (int j=0 ; j<=n ; ++j)
{
scanf("%d",*(map+i)+j);
}
floyd();
memset (dp , 63 , sizeof(dp));
for (int i=0 ; i<(2<<n) ; ++i)
{
for (int j=0 ; j<=n ; ++j)
{
dp[1<<j][j]=map[0][j];
//if(i==1<<j)dp[i][j]=map[0][j];这个和上面的语句都能AC
if(i&(1<<j))
for (int k=0 ; k<=n ; ++k)
{
if((i-(1<<j)) & (1<<k))//第k位为1,第j位不为1的状态
dp[i][j]=min(dp[i-(1<<j)][k]+map[k][j],dp[i][j]);
}
//printf("%d %d %d\n",i,j,dp[i][j]);
}
}
int ans=dp[(2<<n)-1][0];
for (int i=1 ; i<=n ; ++i)
{
ans=min(dp[(2<<n)-1][i]+map[i][0],ans);
}
printf("%d\n",ans);
}
return 0;
}