HDU 5067 Harry And Dig Machine(状压dp)

感觉这两天怎么老是遇到状压啊。。。。

数字20以下,首想状压啊、、、

不过这题犯抽忘记考虑没有石头的时候了啊。

简单的状压:表示状态为j时以第i的作为结束。

PS:这题也在表扬大蓝翔的挖掘机技术啊。醉了啊。。。

Harry And Dig Machine

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 468    Accepted Submission(s): 170

Problem Description

As we all know, Harry Porter learns magic at Hogwarts School. However, learning magical knowledge alone is insufficient to become a great magician. Sometimes, Harry also has to gain knowledge from other certain subjects, such as language, mathematics, English,
and even algorithm.

Dumbledore, the headmaster of Hogwarts, is planning to construct a new teaching building in his school. The area he selects can be considered as an n*m grid, some (but no more than ten) cells of which might contain stones. We should remove the stones there
in order to save place for the teaching building. However, the stones might be useful, so we just move them to the top-left cell. Taking it into account that Harry learned how to operate dig machine in Lanxiang School several years ago, Dumbledore decides
to let him do this job and wants it done as quickly as possible. Harry needs one unit time to move his dig machine from one cell to the adjacent one. Yet skilled as he is, it takes no time for him to move stones into or out of the dig machine, which is big
enough to carry infinite stones. Given Harry and his dig machine at the top-left cell in the beginning, if he wants to optimize his work, what is the minimal time Harry needs to finish it?

Input

They are sever test cases, you should process to the end of file.

For each test case, there are two integers n and m.(1≤n,m≤50).

The next n line, each line contains m integer. The j-th number of ith line
a[i][j] means there are a[i][j] stones on the jth cell
of the ith line.( 0≤a[i][j]≤100 ,
and no more than 10 of a[i][j] will be positive integer).

Output

For each test case, just output one line that contains an integer indicate the minimal time that Harry can finish his job.

Sample Input

3 3
0 0 0
0 100 0
0 0 0
2 2
1 1
1 1

Sample Output

4
4

Source

BestCoder Round #14

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL __int64
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898

const int maxn = 55;
int mp[maxn][maxn];
int n, m;
int dis[maxn][maxn];
using namespace std;
int dp[12][1<<12];

struct node
{
    int x, y;
} f[12];

int main()
{
    while(~scanf("%d %d", &n, &m))
    {
        int ans = 0;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                scanf("%d",&mp[i][j]);
                if(mp[i][j])
                {
                    f[ans].x = i;
                    f[ans++].y = j;
                }
            }
        }
        memset(dis, 0, sizeof(dis));
        for(int i = 0; i < ans; i++)
            for(int j = 0; j < ans; j++) dis[i][j] = (abs(f[i].x-f[j].x)+abs(f[i].y-f[j].y));
        for(int i = 0; i < ans; i++)
            for(int j = 0; j < (1<<ans); j++) dp[i][j] = INF;
        for(int i = 0; i < ans; i++) dp[i][(1<<i)] = (abs(f[i].x-1)+abs(f[i].y-1));
        for(int j = 0; j < (1<<ans); j++)
        {
            for(int k = 0; k < ans; k++)
            {
                if(!(j&(1<<k))) continue;
                for(int p = 0; p < ans; p++)
                {
                    if(j&(1<<p)) continue;
                    dp[p][j|(1<<p)] = min(dp[k][j] + dis[k][p], dp[p][j|(1<<p)]);
                }
            }
        }
        int Min = INF;
        for(int i = 0; i < ans; i++) Min = min(Min, dp[i][(1<<ans)-1]+abs(f[i].x-1)+abs(f[i].y-1));
        if(Min == INF) Min = 0;
        printf("%d\n",Min);
    }
    return 0;
}
时间: 2024-07-28 19:52:56

HDU 5067 Harry And Dig Machine(状压dp)的相关文章

HDU 5067 Harry And Dig Machine(状压DP)(TSP问题)

题目地址:pid=5067">HDU 5067 经典的TSP旅行商问题模型. 状压DP. 先分别预处理出来每两个石子堆的距离.然后将题目转化成10个城市每一个城市至少经过一次的最短时间模型.然后简单的状压DP就可以. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #incl

HDOJ 5067 Harry And Dig Machine 状压DP

状压DP....dp[i][j]已经走过的点的状态,目前再j点的最小距离 Harry And Dig Machine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 560    Accepted Submission(s): 210 Problem Description As we all know, Harry Porter le

hdu 5067 Harry And Dig Machine (状态压缩dp)

题目链接 bc上的一道题,刚开始想用这个方法做的,因为刚刚做了一个类似的题,但是想到这只是bc的第二题, 以为用bfs水一下就过去了,结果MLE了,因为bfs的队列里的状态太多了,耗内存太厉害. 题意: 从某一点出发,遍历网格上的一些点,每个点至少访问一次需要的最小时间是多少. 官方题解: 由于Harry的dig machine是无限大的,而装载石头和卸载石头是不费时间的,所以问题可以转化成:从某一点出发,遍历网格上的一些点,每个点至少访问一次需要的最小时间是多少.这就是经典的旅行商问题,考虑到

HDU 5067 Harry And Dig Machine(状压dp)

HDU 5067 Harry And Dig Machine 思路:由于点才10个,在加上一个起点,处理出每个点之间的曼哈顿距离,然后用状压dp搞,状态表示为: dp[i][s],表示在i位置,走过的点集合为s的最小代价 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int N = 15;

HDU 4856 Tunnels (最短路+状压DP)

题意:给你N*N的网格,'.'表示可以走,'#'表示不能走,m条管道,每条管道有起点和终点坐标, Bob每次可以走到相邻的网格花费1s,问Bob走完m条管道要花多少时间:Bob在管道内不计算时间 即计算Bob从管道 i 的出口走到管道 j 的入口的时间Dis(e[i],s[j])的最小和,起点可以任意: 思路:看了题解说是状态压缩DP然后深入理解了下. 首先算出d[e[i]][s[j]]的最短距离,不能到达为-1: dp[i][j] : 表示以 j 为起点状态为 i 的最小值.其中 i 是用十进

hdu 5067 Harry And Dig Machine(BestCoder Round #14)

Harry And Dig Machine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 332    Accepted Submission(s): 104 Problem Description As we all know, Harry Porter learns magic at Hogwarts School. Howeve

HDU 1074:Doing Homework(状压DP)

http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7704    Accepted Submission(s): 3484 Problem Description Ignatius has just come bac

HDU 6149 Valley Numer II(状压DP)

题目链接 HDU6149 百度之星复赛的题目……比赛的时候并没有做出来. 由于低点只有15个,所以我们可以考虑状压DP. 利用01背包的思想,依次考虑每个低点,然后枚举每个状态. 在每个状态里面任意枚举不在这个状态中的两个点,如果能构成一个valley,那么更新答案. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i,

hdu 2167 方格取数 【状压dp】(经典)

<题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的  3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数字周围8个点都不能取,问:取得数字的最大和为多少? 解题分析: 由于对每一个数,有选和不选两种可能,分别对应状态压缩中的1和0,且 n<=15,1<<15不是非常大,因此就可以非常自然的想到状态压缩. 此题要与普通的状压dp不同的是,当某一行取某种方案时,如何求出这种取数的所有取得的数之和,