[BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]
题目链接 : BZOJ 1085
题目分析 :
本题中可能的状态会有 (2^24) * 25 种状态,需要使用优秀的搜索方式和一些优化技巧。
我使用的是 IDA* 搜索,从小到大枚举步数,每次 DFS 验证在当前枚举的步数之内能否到达目标状态。
如果不能到达,就枚举下一个步数,重新搜索,即使某些状态在之前的 DFS 中已经搜索过,我们仍然搜索。
并且在一次 DFS 中,我们不需要判定重复的状态。
在 IDA* 中,重要的剪枝优化是 估价函数 ,将一些不可能存在可行解的枝条剪掉。
如果估价函数写得高效,就能有极好的效果。我们写估价函数的原则是,绝对不能剪掉可能存在可行解的枝条。
因此,在预估需要步数时,应让估计值尽量接近实际步数,但一定不能大于实际需要的步数。
本题的一个很有效的估价函数是,比较当前状态的黑白骑士与目标状态的黑白骑士有多少不同,我们把这个值作为估价函数值,因为每一步最多将当前状态的一个骑士改变为与目标状态相同。但是应该注意的是,空格所在的格子不要算入其中。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MaxStep = ;
const int Dx[] = {, , -, -, , , -, -}, Dy[] = {, -, , -, , -, , -};
int Te, Ans;
char Str[];
struct ES
{
int num, pos;
bool operator == (const ES &e) const {
return (num == e.num) && (pos == e.pos);
}
} S, T;
inline bool Inside(int x, int y) {
if (x < || x > ) return false;
if (y < || y > ) return false;
return true;
}
void Print(ES x) {
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
if (x.pos == (i * + j)) printf("*");
else {
if (x.num & ( << (i * + j))) printf("");
else printf("");
}
}
printf("\n");
}
}
inline int Expect(ES x) {
int Temp, Cnt;
Temp = x.num ^ T.num;
Cnt = ;
if (x.pos != T.pos) {
if (Temp & ( << T.pos)) --Cnt;
if (Temp & ( << x.pos)) --Cnt;
}
while (Temp) {
++Cnt;
Temp -= Temp & -Temp;
}
return Cnt;
}
bool DFS(ES Now, int Step, int Limit) {
if (Now == T) return true;
if (Step == Limit) return false;
if (Expect(Now) > Limit - Step) return false;
int x, y, xx, yy;
ES Next;
x = Now.pos / ; y = Now.pos % ;
for (int i = ; i < ; i++) {
xx = x + Dx[i]; yy = y + Dy[i];
if (!Inside(xx, yy)) continue;
Next = Now;
Next.pos = xx * + yy;
Next.num &= ( << ) - - ( << (xx * + yy));
if (Now.num & ( << (xx * + yy))) Next.num |= ( << (x * + y));
if (DFS(Next, Step + , Limit)) return true;
}
return false;
}
int IDAStar(ES S) {
if (S == T) return ;
for (int i = ; i <= MaxStep; ++i)
if (DFS(S, , i)) return i;
return -;
}
int main()
{
scanf("%d", &Te);
T.num = ; T.pos = ;
for (int Case = ; Case <= Te; ++Case) {
S.num = ;
for (int i = ; i < ; ++i) {
scanf("%s", Str);
for (int j = ; j < ; ++j) {
if (Str[j] == '') S.num |= ( << (i * + j));
if (Str[j] == '*') S.pos = i * + j;
}
}
Ans = IDAStar(S);
printf("%d\n", Ans);
}
return ;
}
[BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]的更多相关文章
- bzoj 1085 [SCOI2005]骑士精神——IDA*
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 迭代加深搜索. 估价函数是为了预计步数来剪枝,所以要优于实际步数. 没错,不是为了确定 ...
- bzoj 1085: [SCOI2005]骑士精神 IDA*
题目链接 给一个图, 目标位置是确定的, 问你能否在15步之内达到目标位置. 因为只有15步, 所以直接ida* #include<bits/stdc++.h> using namespa ...
- Bzoj 1085: [SCOI2005]骑士精神 (dfs)
Bzoj 1085: [SCOI2005]骑士精神 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 dfs + 剪枝. 剪枝方法: ...
- BZOJ 1085: [SCOI2005]骑士精神( IDDFS + A* )
一开始写了个 BFS 然后就 T 了... 这道题是迭代加深搜索 + A* -------------------------------------------------------------- ...
- BZOJ 1085 [SCOI2005]骑士精神 【A*启发式搜索】
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2838 Solved: 1663 [Submit][St ...
- bzoj 1085: [SCOI2005]骑士精神
Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士,且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵 ...
- [BZOJ 1085][SCOI2005]骑士精神(IDA*)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1085 分析: 首先第一感觉是宽搜,但是空间需要8^15*5*5,明显不够,又鉴于最大深 ...
- BZOJ.1085.[SCOI2005]骑士精神(迭代加深搜索)
题目链接 最小步数这类,适合用迭代加深搜索. 用空格走代替骑士. 搜索时记录上一步防止来回走. 不需要每次判断是否都在位置,可以计算出不在对应位置的骑士有多少个.而且每次复原一个骑士至少需要一步. 空 ...
- BZOJ 1085: [SCOI2005]骑士精神(A*算法)
第一次写A*算法(这就是A*?如果这就是A*的话,那不就只是搜索的一个优化了= =,不过h函数如果弄难一点真的有些难设计) 其实就是判断t+h(x)(t为当前步数,h(x)为达到当前状态的最小步数) ...
随机推荐
- UVA - 10785 The Mad Numerologist
题目链接 这个题又犯了省题不清的错误.导致不停 wa.唉. 题目意思是给你一个长度L,然后和一张表相应每一个大写字母的value值.你须要依照一定规则找出长度为L的序列. 注意 序列的value值要 ...
- Hibernate的游离态与持久态转换
在Hibernate中,一个PO可能经过长时间的操作,session已过时关闭,此时PO已经是一个游离态的对象,这时要转换为持久战态,有下面几种方法: 1.session.saveOrUpdate(o ...
- jQuery日期联动插件
此版本为网上的日期联动插件修改版,加入了修改后事件 /* * jQuery Date Selector Plugin * 日期联动选择插件 * * Demo: $("#calendar&qu ...
- Linux写配置HDF5的python包h5py
闲言碎语不讲,直接进入正题.Python在科学计算的应用越来越丰度,而hdf(5)数据的应用也非常广泛.python提供了h5py包供开发者处理数据(http://www.h5py.org/).在wi ...
- Android layout的横竖屏处理
一.layout-land和layout-prot的区别与使用 默认情况下,创建的Android项目里只有一个layout文件夹,尽管这样也可以横竖屏切换用,但是某些布局横屏过后闲的格外的丑,如下图 ...
- XFire构建服务端Service的两种方式(转)
XFire构建服务端service的两种方式,一是用xfire构建,二是和spring集成构建. 一,xifre构建,确保把xfire的jar包导入到工程中或classpath. 1,service的 ...
- An App ID with Identifier 'xxxxxx’ is not available. Please ....
1.完全关闭Xcode; 2.找到钥匙串,将钥匙串(Keychain)中的对应证书移除: 3.再次打开Xcode,通过 Preferences - Account 4. 删除原先的账号重新登录, 搞定 ...
- PV、UV、IP的区别
网站推广需要一个网站访问统计工具,常用的统计工具有百度统计.51la.量子恒道统计等.网站访问量常用的指标为PV.UV.IP.那么什么是PV.UV和IP,PV.UV.IP的区别是什么? --首先来看看 ...
- 对数据预处理的一点理解[ZZ]
数据预处理没有统一的标准,只能说是根据不同类型的分析数据和业务需求,在对数据特性做了充分的理解之后,再选择相关的数据预处理技术,一般会用到多种预处理技术,而且对每种处理之后的效果做些分析对比,这里面经 ...
- javascript——面向对象程序设计(2)
<script type="text/javascript"> //1.理解原型对象 //2.原型与in操作符 //3.更简单的原型语法 //4.原型的动态性 //5. ...