题目链接:http://poj.org/problem?id=3311
题目大意:一个送披萨的,每次送外卖不超过10个地方,给你这些地方之间的时间,求送完外卖回到店里的总时间最小。
Sample Input
3 0 1 10 10 1 0 1 2 10 1 0 10 10 2 10 0 0
Sample Output
8
分析:dp[i][j]:表示在i状态(用二进制表示城市有没有经过)时最后到达j城市的最小时间,转移方程:dp[i][j]=min(dp[i][k]+d[k][j],dp[i][j]) d[k][j]是k城市到j城市的最短距离,显然要先用flody处理一下。
代码如下:
1 # include<stdio.h> 2 # include<string.h> 3 int map[11][11],n,m,dp[1<<11][11]; 4 const int INF = 1<<30; 5 6 int min(int a,int b){ 7 return a<b ?a :b; 8 } 9 10 void flody(){ 11 int i,j,k; 12 for(k=0; k<=n; k++) 13 for(i=0; i<n; i++) 14 for(j=0; j<=n; j++){ 15 if(map[i][k] + map[k][j] < map[i][j]) 16 map[i][j] = map[i][k] + map[k][j]; 17 } 18 } 19 int main(){ 20 int i,j,k; 21 while(scanf("%d",&n) && n){ 22 for(i=0; i<=n; i++) 23 for(j=0; j<=n; j++) 24 scanf("%d",&map[i][j]); 25 flody(); 26 int ans = INF; 27 for(i=0; i<(1<<n); i++) 28 for(j=1; j<=n; j++) 29 if(i==(1<<(j-1))) 30 dp[i][j] = map[0][j]; 31 else 32 if(i & (1<<(j-1))){ 33 dp[i][j] = INF; 34 for(k=1; k<=n; k++) 35 if(k!=j && (i & (1<<(k-1)))) 36 dp[i][j] = min(dp[i^(1<<(j-1))][k] + map[k][j],dp[i][j]); 37 } 38 for(i=1; i<=n; i++) 39 ans = min(ans, dp[(1<<n)-1][i]+map[i][0]); 40 printf("%d ",ans); 41 } 42 return 0; 43 }