[POJ3311]Hie With The Pie

[POJ3311]Hie With The Pie 

题目大意: 
一个送外卖的人,从0点出发,要经过所有的地点然后再回到店里(就是0点),求最少花费的代价。 
输入 
1<=n<=10 
输出 
一个整数,代表最小花费。 
样例输入 

0 1 10 10 
1 0 1 2 
10 1 0 10 
10 2 10 0 

样例输出 

_______________________________________________________________________________________________

状态压缩动态规划

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 }
View Code

猜你喜欢

转载自www.cnblogs.com/gryzy/p/9835971.html