【SCOI2005】骑士精神(IDA*)

IDA*=迭代加深+估价函数

A*=BFS(优先队列)+估价函数

迭代加深通常用于:

1.在有一定的限制条件时使用(例如本题中“如果能在15步以内到达目标状态,则输出步数,否则输出-1“)。

2.题目中说输出所有中的任何一组解。

相当于对于一颗很深的搜索树,我们限制它的层数,类似于广搜,尽可能遍历更多的分支。

evaluate:估价函数,本题中是将目标棋盘与当前棋盘作比较,注意估价函数表示的是“最优情况下(即使有可能实现不了)”的步数。

#include
using namespace std;
int f=0;
int dx[9]={0,1,1,-1,-1,2,2,-2,-2};
int dy[9]={0,2,-2,2,-2,1,-1,1,-1}; 
char m[6][6];
char ex[6][6]=
{
	{'0','0','0','0','0','0'},	
	{'0','1','1','1','1','1'}, 
	{'0','0','1','1','1','1'},
	{'0','0','0','*','1','1'},
	{'0','0','0','0','0','1'},
	{'0','0','0','0','0','0'},
};
inline int evaluate()
{
	int cnt=0;
	for(int i=1;i<=5;i++)
		for(int j=1;j<=5;j++)
			if(m[i][j]!=ex[i][j])	cnt++;
	return cnt-1;
}
void dfs(int dep,int x,int y,int lx,int ly,int lim)	
{
	if(dep==lim)
	{
		if(evaluate()==-1)	f=1;
		return;
	}
	for(int i=1;i<=8;i++)
	{
		int px=x+dx[i]; int py=y+dy[i];
		if(px==lx&&py==ly)	continue;
		if(px<1||px>5||py<1||py>5)	continue;
		swap(m[x][y],m[px][py]);
		if(evaluate()+dep+1<=lim)
			dfs(dep+1,px,py,x,y,lim);
		swap(m[x][y],m[px][py]);
	}
}
int main()
{
	int T,sx,sy;
	cin>>T;
	while(T--)
	{
		f=0; 
		char ch;
		for(int i=1;i<=5;i++)
			for(int j=1;j<=5;j++)
			{
				cin>>ch;
				m[i][j]=ch;
				if(ch=='*')	sx=i,sy=j;	
			}
		for(int d=1;d<=15;d++)
		{
			dfs(0,sx,sy,sx,sy,d);
			if(f)
			{
				cout<

 

你可能感兴趣的:(【SCOI2005】骑士精神(IDA*))