java货郎担问题求解_货郎担问题(TSP)

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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值