P2324 [SCOI2005]骑士精神

A*与爆搜的不同就是它有一个估价函数$h(x)$

这个估价函数一般设为从当前状态到终点状态的估计最短步数,这样可以有效剪枝

但估计值必须严格小于等于实际剩余步数,否则会剪枝过度而影响正确性

$g(x),f(x)$分别为剩余步数和已走步数,则:

$g(x)=f(x)+h(x)$

本题中的$h(x)$可以设为未归位的棋子数+1

因为每一步最多使一个棋子归位(除最后一步一次归位2个棋子)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int d1[]={,,,,-,-,-,-};
int d2[]={,-,,-,,-,,-};
char a[][]; int re,col[][];
inline bool is(int x,int y){return (x==&&y==)?(a[x][y]=='*'):(a[x][y]==col[x][y]+'');}
void dfs(int d,int s,int x,int y){//d当前步数,s已归位棋子个数
if(d+-s>=re||d>) return ;//f(x)=d,g(x)=24-s
if(s==) {re=min(re,d); return ;}
for(int i=;i<;++i){
int rx=x+d1[i],ry=y+d2[i],p=s;
if(rx<||<rx||ry<||<ry) continue;
p-=is(x,y)+is(rx,ry);
swap(a[x][y],a[rx][ry]);
p+=is(x,y)+is(rx,ry);
dfs(d+,p,rx,ry);
swap(a[x][y],a[rx][ry]);
}
}
int main(){
for(int i=;i<=;++i) for(int j=i;j<=;++j) col[i][j]=;
col[][]=col[][]=;
int T,sum,fx,fy;scanf("%d",&T);
while(T--){
sum=; re=;
for(int i=;i<=;++i){
scanf("%s",a[i]+);
for(int j=;j<=;++j){
sum+=is(i,j);
if(a[i][j]=='*') fx=i,fy=j;
}
}dfs(,sum,fx,fy);
if(re>) re=-;
printf("%d\n",re);
}return ;
}

最新文章

  1. 《HiWind企业快速开发框架实战》(3)使用HiWind创建和管理菜单
  2. Python语法二
  3. EMIF接口的寻址问题
  4. wso2esb简介
  5. poj1379 模拟退火
  6. java编程思想-java 异常使用指南
  7. C#生成条形码 Code128算法
  8. iOS UIApplicatin和它的delegate
  9. Unity UI和引用的管理中心
  10. putty修改编码
  11. 路由页面缓存开启 以及 keep-alive 给你埋下的坑
  12. 关于Hibernate
  13. 用UE4来做Zego即构的房间列表
  14. dubbo的架构
  15. C++实验1
  16. iOS中 Realm错误总结整理 韩俊强的博客
  17. Nigix配置
  18. JavaWeb基础—数据库连接池DBCP、C3P0
  19. linux计划任务 学习笔记
  20. bash 基础

热门文章

  1. MySQL 简介
  2. linux系统安装telnet服务
  3. Linux–Nginx攻略
  4. TypeScript扩展类方法
  5. Springboot 默认cache
  6. bzoj4771 七彩树 dfs序+主席树+树链的并
  7. poj 3468 : A Simple Problem with Integers 【线段树 区间修改】
  8. 在一个div上增加遮罩
  9. Task4.文本表示:从one-hot到word2vec
  10. 持续优化云原生体验,阿里云在Serverless容器与多云上的探索