http://acm.hdu.edu.cn/showproblem.php?pid=5067
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define LL long long
const int INF=0x3f3f3f3f;
int mp[55][55];
int e[30][30];
int dp[20][1<<15];
struct note
{
int x,y;
} stone[30];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int cnt=0;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
int t;
scanf("%d",&t);
if(t!=0)
{
stone[cnt].x=i;
stone[cnt++].y=j;
}
}
memset(e,0,sizeof(e));
for(int i=0; i<cnt; i++)
for(int j=0; j<cnt; j++)
{
e[i][j]=abs(stone[i].x-stone[j].x)+abs(stone[i].y-stone[j].y);
}
memset(dp,INF,sizeof(dp));
for(int i=0; i<cnt; i++)
dp[i][1<<i] = (abs(stone[i].x-1)+abs(stone[i].y-1));
for(int j = 0; j < (1<<cnt); j++)
for(int k = 0; k < cnt; k++)
for(int p = 0; p < cnt; p++)
if(p != k && (j & (1 << k)) > 0 && (j & (1 << p)) == 0)
{
dp[p][j|(1<<p)] = min(dp[k][j] + e[k][p], dp[p][j|(1<<p)]);
}
int Min = INF;
for(int i = 0; i <cnt; i++) Min = min(Min, dp[i][(1<<cnt)-1]+abs(stone[i].x-1)+abs(stone[i].y-1));
if(Min == INF) Min = 0;
printf("%d
",Min);
}
}