n个城市,两两之间均有道路连接,长度已知。先有一人从某一城市出发,所有城市经过一次且只能经过一次。求最小的总路程。
DP方程:设起点为城市0(最终路径是个环,起点在哪都不影响),设D[i][S]为当前在城市i,将集合S中的城市全部走一遍,再回到城市0的最小总长度。
D[i][S]=min{D[j][S-{j}]+dist[i][j] | j in S}
起始状态:d[i][空集]=dist[0][i] (走一步就回来了)
最终状态:d[0][{1,2,3……n-1}]
时间复杂度:O(n2*2n) (枚举需要O(n)时间)
#include
#include
#include
#include
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define read(x) scanf("%d",&x)
using namespace std;
const int maxn=15+1;
const int inf=100000000;
int dist[maxn][maxn],d[maxn][(1<
bool vis[maxn][(1<
int dp(int k,int s)
{
if (vis[k][s]) return d[k][s];
vis[k][s]=1;
d[k][s]=inf;
rep(i,0,n-1)
if ((1<
return d[k][s];
}
int solve()
{
memset(vis,0,sizeof(vis));
rep(i,0,n-1) {d[i][0]=dist[0][i];vis[i][0]=1;}
return dp(0,(1<
}
int main()
{
read(n);
rep(i,0,n-1)
rep(j,0,n-1)
read(dist[i][j]);
printf("%d\n",solve());
return 0;
}