hdu4090 双重dfs模拟 + 启发式搜索
来源:互联网 发布:诺基亚衰落的原因知乎 编辑:程序博客网 时间:2024/06/07 06:49
题意:消消乐,每次必须消除数量大于等于3个,而且得分是消除个数的平方,每次消除之后局面往左下角收拢.
分析:
- 首先很容易想到对每个当前局面枚举每种颜色来dfs消除,注意这里对每一个已经消除过度页面要vis记录
要不然超时,比赛的时候记录了,但是初始化vis的地方写错了,导致TLE,交换了顺序就AC….看来代码逻辑还是
不够清晰,不能完整表达正确的想法,而且出现了错误不能很快正确的debug.
- 对当前局面消除了之后,用类似unique函数的实现方式,模拟处理之后的局面再进行搜索,所以这里是两层
dfs嵌套.
- 这里的一个核心剪枝是启发式剪枝,假设当前局面的最优结果来和答案比较.
Get:
代码能力很重要,平时要正确一次AC的能力.
/************************************************ *Author :jibancanyang *Created Time :2016年05月04日 星期三 15时55分49秒 ***********************************************/#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;typedef pair<int, int> pii;typedef long long ll;typedef unsigned long long ull;vector<int> vi;#define xx first#define yy second#define lowbit(x) (x&-x)#define sa(n) scanf("%d", &(n))#define rep(i, a, n) for (int i = a; i < n; i++)#define vep(c) for(decltype((c).begin() ) it = (c).begin(); it != (c).end(); it++) #define pr(x) cout << #x << " " << x << " "#define prln(x) cout << #x << " " << x << endlconst int mod = int(1e9) + 7, INF = 0x3f3f3f3f, maxn = 1e5 + 12;int dirx[] = {-1, -1, 0, 1, 1, 1, 0, -1};int diry[] = {0, 1, 1, 1, 0, -1, -1, -1};int co[7];int G[9][9];int n, m, k, ans, cnt;bool vis[9][9];void pt(void) { prln(ans); cout << "co: " << endl; rep (i, 1, k + 1) cout << i << ": " << co[i] << " " ; cout << endl; cout << "G: " << endl; rep (i, 1, n + 1) { rep (j , 1, m + 1) { cout << G[i][j] << " "; } cout << endl; }}int dfs1(int x, int y, int c) { int ret = 1; vis[x][y] = true; G[x][y] = -1; rep (i, 0, 8) { int u = x + dirx[i], v = y + diry[i]; if (u > 0 && u <= n && v > 0 && v <= m && !vis[u][v] && G[u][v] == c) { ret += dfs1(u, v, c); } } return ret;}void pre(void) { int ed = 1; int GG[9][9]; rep (i, 1, n + 1) rep (j, 1, m + 1) GG[i][j] = -1; for (int i = 1; i <= m; i++) { int st = n; bool ok = false; for (int j = n; j > 0; j--) { if (G[j][i] != -1) ok = true, GG[st--][ed] = G[j][i]; } if (ok) ed++; } memcpy(G, GG, sizeof(G));}void dfs(int p) { int temp = 0; rep (i, 1, k + 1) if (co[i] >= 3) temp += co[i] * co[i]; ans = max(ans, p); if (temp + p <= ans) return; memset(vis, 0, sizeof(vis)); rep (i, 1, k + 1) { if (co[i] >= 3) { rep (a, 1, n + 1) { rep (b, 1, m + 1) { if (G[a][b] == i && !vis[a][b]) { int Gtemp[9][9]; memcpy(Gtemp, G, sizeof(G)); bool sd[9][9]; int kk = dfs1(a, b, i); memcpy(sd, vis, sizeof(vis)); co[i] -= kk; if (kk >= 3) pre(), dfs(p + kk * kk); co[i] += kk; memcpy(vis, sd, sizeof(vis)); memcpy(G, Gtemp, sizeof(G)); } } } } }}int main(void){#ifdef LOCAL freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);#endif while (~scanf("%d%d%d", &n, &m, &k) ) { // if (T++) break; ans = 0; memset(co, 0, sizeof(co)); rep (i, 1, n + 1) rep (j, 1, m + 1) sa(G[i][j]), co[G[i][j]]++; dfs(0); printf("%d\n", ans); } return 0;}
0 0
- hdu4090 双重dfs模拟 + 启发式搜索
- hdu4090 GemAnd Prince (搜索+剪枝)
- uva12112 - Iceman BFS模拟 启发式搜索
- 【HDU4090】Gem and Prince-DFS+可行性剪枝
- 启发式搜索
- 启发式搜索
- 启发式搜索
- 启发式搜索
- 启发式搜索
- 启发式搜索
- hdu2718双重dfs+剪枝
- 启发式搜索算法
- 【启发式搜索】Remmarguts' Date
- 启发式搜索算法
- 贪心算法::启发式搜索
- 启发式搜索技术 A*
- A*启发式搜索
- A*启发式搜索基础
- 习题三 1001
- JavaScript-----判断Caps Lock是否开启
- 《VR入门系列教程》之5---应用方向
- c++第五次实验——求和
- Coincidence
- hdu4090 双重dfs模拟 + 启发式搜索
- 修改oracle awr修改信息收集频率
- 最长公共字序列
- Android基础 | Activity间进行数据传递
- SQL Server 别名数据类型
- 《VR入门系列教程》之6---VR硬件介绍及DK1
- C++实验5——数组分离
- Ubuntu, Mac 下 Web 开发环境搭建:node.js, golang 与 revel 配置安装
- NSString拼接