[POJ3311]Hie With The Pie
[POJ3311]Hie With The Pie
题目大意:
一个送外卖的人,从0点出发,要经过所有的地点然后再回到店里(就是0点),求最少花费的代价。
输入
1<=n<=10
输出
一个整数,代表最小花费。
样例输入
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0
样例输出
8
_______________________________________________________________________________________________
状态压缩动态规划
f[s][i]:表示已经走过了s状态的点,最有停留在i点,当然i点要在s状态内,的最短路。
f[s][i]=min(f[s'][j]+dis[j][i]),条件s'比s状态只少i点
当然最后要加上i点到0号点的距离。
不要忘记floyd!!
_______________________________________________________________________________________________
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 int f[1<<10][11]; 7 int dis[11][11],n; 8 9 void init() 10 { 11 memset(f,0x7f,sizeof(f)); 12 for(int i=0;i<n;++i)f[(1<<i)][i+1]=dis[0][i+1]; 13 } 14 void dp(int s,int las) 15 { 16 if(s==0)return ; 17 if(f[s][las]!=0x7f7f7f7f)return ; 18 int ss=s^(1<<(las-1)); 19 for(int i=0;i<n;++i) 20 { 21 if((ss&(1<<i))) 22 { 23 dp(ss,i+1); 24 f[s][las]=min(f[s][las],f[ss][i+1]+dis[i+1][las]); 25 } 26 } 27 } 28 void floyd() 29 { 30 for(int k=0;k<=n;++k) 31 for(int i=0;i<=n;++i) 32 for(int j=0;j<=n;++j) 33 if(dis[i][j]>dis[i][k]+dis[k][j])dis[i][j]=dis[i][k]+dis[k][j]; 34 } 35 int main() 36 { 37 while(scanf("%d",&n)==1 && n) 38 { 39 for(int i=0;i<=n;++i) 40 for(int j=0;j<=n;++j) 41 scanf("%d",&dis[i][j]); 42 floyd(); 43 init(); 44 long long ans=0x7fffffffffffffff; 45 for(int i=1;i<=n;++i) 46 { 47 dp((1<<n)-1,i); 48 if(f[(1<<n)-1][i]+dis[i][0]<ans)ans=f[(1<<n)-1][i]+dis[i][0]; 49 } 50 printf("%lld\n",ans); 51 } 52 return 0; 53 }