HDU 4127 Flood-it!(IDA*)

来源:互联网 发布:中文域名转码器 编辑:程序博客网 时间:2024/05/16 02:53

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4127


题意:给出N * N的方格,每种格子有初始颜色(0 ~ 5共计6种),每次可以选择一种颜色,使得与左上联通块相连的格子(邻接格或者与邻接格颜色相同的格子)全部变成该颜色,求最少的次数使得所有格子颜色相同


思路:第一次写IDA*,通过枚举深度上限depth再设计估价函数求解,对于估价函数,可以先预计一个下界H(),如果当前层 cur + H() > depth时进行剪枝


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <utility>#include <cmath>#include <queue>#include <set>#include <map>#include <climits>#include <functional>#include <deque>#include <ctime>#include <string>#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long ll;const int maxn = 10;int dx[4] = {1, 0, -1, 0};int dy[4] = {0, -1, 0, 1};int n, maxh;int g[maxn][maxn], vis[maxn][maxn];//vis值为1表示与左上块联通,为2表示与左上块相邻bool ok(int x, int y){if (x < 0 || x >= n || y < 0 || y >= n) return false;return true;}void dfs(int x, int y, int c){vis[x][y] = 1;for (int i = 0; i < 4; i++){int nx = x + dx[i];int ny = y + dy[i];if (!ok(nx, ny) || vis[nx][ny]) continue;if (vis[nx][ny] == 1) continue;if (g[nx][ny] == c)dfs(nx, ny, c);elsevis[nx][ny] = 2;}}//计算该染色新增的格子数int cal_num(int c){int res = 0;for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){if (g[i][j] == c && vis[i][j] == 2){res++;dfs(i, j, c);}}}return res;}//至少还要染色多少次,作为估价函数int H(){int res = 0;bool used[10];memset(used, false, sizeof(used));for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){if (vis[i][j] != 1 && !used[g[i][j]]){res++;used[g[i][j]] = true;}}}return res;}int lim;bool IDA(int dep){if (dep == lim) return H() == 0;if (dep + H() > lim) return false;int tmp[maxn][maxn];for (int i = 0; i < 6; i++){memcpy(tmp, vis, sizeof(vis));if (cal_num(i) == 0) continue;if (IDA(dep + 1)) return true;memcpy(vis, tmp, sizeof(tmp));}return false;}int main(){while (~scanf("%d", &n) && n){for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)scanf("%d", &g[i][j]);memset(vis, false, sizeof(vis));dfs(0, 0, g[0][0]);lim = H();while (true){if (IDA(0)) break;lim++;}cout << lim << endl;}return 0;}




0 0
原创粉丝点击