poj 3311(状态压缩dp)
来源:互联网 发布:uefi linux 编辑:程序博客网 时间:2024/06/06 01:47
/* dp[s][i] =min{dp[s][i],dp[s'][j]+map[j][i]} map[j][i]为j到i的最短距离*/ #include <stdio.h>#include <string.h>#define inf 100000000 int map[12][12]; int dp[1<<11][12];int min(int x,int y){ if(x<y) return x; return y; }int main(){ int n; while(scanf("%d",&n)!=EOF) { if(n==0) break; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) scanf("%d",&map[i][j]); for(int k=0;k<=n;k++) for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) if(map[i][j]>map[i][k]+map[k][j]) map[i][j]=map[i][k]+map[k][j]; // memset(dp,-1,sizeof(dp)); for(int s=0;s<(1<<n);s++) //所有的状态 { for(int i=1;i<=n;i++) { if(s&(1<<(i-1))) // 状态s中经过i城市 { if(s==(1<<(i-1))) // 状态s中只经过i城市 dp[s][i] = map[0][i]; else // 经过多个城市 { dp[s][i]=inf; for(int j=1;j<=n;j++) { if(s&(1<<(j-1)) && i!=j) ///枚举不是城市I的其他城市 dp[s][i] = min(dp[s][i],dp[s^(1<<(i-1))][j]+map[j][i]); //在没经过城市i的状态中,寻找合适的中间点J使得距离更短 } } } } } int ans=dp[(1<<n)-1][1]+map[1][0]; for(int i=2;i<=n;i++) { if(dp[(1<<n)-1][i]+map[i][0]<ans) { ans = dp[(1<<n)-1][i]+map[i][0]; } } printf("%d\n",ans); } return 0;}