您的位置:首页 > 其它

HDU 5067 Harry And Dig Machine 状态压缩 DP

2014-10-19 09:27 671 查看
题意:在N*M的方格中,有些地方有石子,现在从左上角出发,把所有的石子捡回来,在回到左上角。向相邻的格子移动的时间为1,求最短的时间。

思路:因为最多只有10个点,所以应该用状态压缩DP。然后就是经典的旅行商问题。

坑:可能没有石子,所有不需要移动,但是在求最后的结果的时候要特判。

代码如下:
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

struct point{
int x,y;
} p[20];
int tot;
int dp[15][1<<15];

int main(void)
{
//freopen("in","r",stdin);
int N,M;
while(~scanf("%d%d", &N, &M)){
tot = 0;
int weight;
for(int i = 0; i < N; ++i)
for(int j = 0; j < M; ++j){
scanf("%d", &weight);
if(weight != 0){
p[tot].x = i;
p[tot].y = j;
tot++;
}
}
memset(dp,0x3f,sizeof(dp));
for(int i = 0; i < tot; ++i)
dp[i][1<<i] = p[i].x + p[i].y;
for(int s = 1; s < (1<<tot); ++s){
for(int i = 0; i < tot; ++i) if(s & (1<<i)){
for(int j = 0; j < tot; ++j) if(!(s & (1<<j)))
dp[j][s|(1<<j)] = min(dp[j][s|(1<<j)],dp[i][s] + abs(p[i].x - p[j].x) + abs(p[i].y - p[j].y));
}
}
int ans = 0x3f3f3f3f;
for(int i = 0; i < tot; ++i)
ans = min(ans,dp[i][(1<<tot)-1] + p[i].x + p[i].y);
if(tot == 0)
ans = 0;
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: