从旅行商问题说起——
给定一个图,n个节点(n<=15),求从a节点出发,经历每个节点仅一次,最后回到a,需要的最短时间。
分析:
设定状态S代表当前已经走过的城市的集合,显然,S<=(1<<n)-1.
dp[k][s]——从a走到k,已经经历过的节点集合为s,按照规则走回a所需要的最短时间。
初始化:dp[k][s]=-1
int DP(int K,int S)
{
if (dp[K][S]!=-1)
{
return dp[K][S];
}
if (K==a && S==(1<<n)-1)
{
//已经走回了A,并且所有点都走过一次
return dp[K][S]=0;
}
dp[K][S]=INF;
for (int i=0;i<adj[K].size();i++)
{
//枚举K的下一个点
int v=edges[adj[K][i]].to;
int dist=edges[adj[K][i]].dist;
if (!(S>>(v-1) & 1))//如果这个点还没有走过
{
int val=DP(v,S | (1<<(v-1)));
if (val!=INF)
{
dp[K][S]=min(dp[K][S],val+dist);
}
}
}
return dp[K][S];
}