题意:
旅行商问题,现在有n个点,从第一个点出发,最后回到原点,但是每个点都要到
过,问怎么才能使花费最少。
思路:
dp[S][v] : 已经到达的点集是S,并且现在在v。
依据这个思想,去寻找下一个最短的路径。
注意:
此题需要先找到最短的路径,再去计算。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 30;
int dp[1<<15][30];
int dis[MAXN][MAXN];
int n;
void Folyd(int n)
{
for(int k = 0;k < n; k++)
for(int i = 0;i < n; i++)
for(int j = 0;j < n; j++)
dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);
}
int rec(int S,int v)
{
if(dp[S][v] >= 0)
return dp[S][v];
if(S == (1<<n)-1 && v == 0)
return 0;
int ans = INF;
for(int u = 0;u < n; u++) {
if(!(S & (1<<u))) {
ans = min(ans,rec(S|(1<<u),u)+dis[v][u]);
}
}
return dp[S][v] = ans;
}
void solve()
{
memset(dp,-1,sizeof(dp));
printf("%d\n",rec(0,0));
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n) != EOF) {
if(n == 0)
break;
n++;
for(int i = 0;i < n; i++) {
for(int j = 0;j < n; j++) {
scanf("%d",&dis[i][j]);
}
}
Folyd(n);
solve();
}
return 0;
}