您的位置:首页 > 其它

hdu 5067 Harry And Dig Machine

2015-03-10 16:01 295 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5067

思路:问题可以转化成:从某一点出发,遍历网格上的一些点,每个点至少访问一次需要的最小时间是多少。这就是经典的旅行商问题,考虑到我们必须要遍历的点只有不到10个,可以用状态压缩解决。

dp[i][j]表示i状态的点被访问过了,当前停留在点j 需要的最少时间,状态转移方程:dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+abs(q[j].x-q[k].x)+abs(q[j].y-q[k].y));

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int inf=1<<30;

int n,m;
int g[100][100];
int dp[1<<11][100];
struct node
{
int x,y;
}st;

int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
vector<node>q;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
scanf("%d",&g[i][j]);
if(i==1&&j==1)
{
st.x=i;
st.y=j;
q.push_back(st);
}
else if(g[i][j])
{
st.x=i;
st.y=j;
q.push_back(st);
}
}
}
int x=q.size();
for(int i=0; i<(1<<x); i++)
{
for(int j=0; j<x; j++)
{
dp[i][j]=inf;
}
}
dp[0][0]=0;
for(int i=0; i<(1<<x); i++)
{
for(int j=0; j<x; j++)
{
for(int k=0; k<x; k++)
{
if((i&(1<<k))) continue;
dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+abs(q[j].x-q[k].x)+abs(q[j].y-q[k].y));
}
}
}
printf("%d\n",dp[(1<<x)-1][0]);
}
return 0;
}


View Code

Dp[i|(1≪k)][k]=min(Dp[i|(1≪k)][k],Dp[i][j]+Dis(j,k))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: