【week1day5笔记】搜索

  • 深度优先搜索
    对于一种情况,直接搜索到边界再进行回溯(有爆栈风险)

  • 广度优先搜索
    往往需要用到队列,一层一层地向下搜索

  • 迭代加深搜索
    兼有深搜与广搜地思路,设置深度上限,依次进行深度优先搜索,当搜索了该深度上限下所有情况时,加深深度继续进行搜索

  • 记忆化搜索
    搜索时记录已搜索过的情况结果,省去下一次搜索的时间,思路上与动态规划有一定相似之处

  • 双向搜索

状态保存
①直接数组保存
②二进制、三进制保存法
③其他

在竞赛中,搜索题的难度往往更体现于编写,查错和剪枝上,处理不当可能会耗费相当长的时间

例题
POJ - 2531 (二进制状态保存)

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int num[30][30];
int count[21]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576};
int n;
void init()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			scanf("%d",&num[i][j]);
}
int main()
{
	init();
	int ans=-1;
	bool flag[21];
	int cnt[21],len;
	for(int x=1;x<count[n]/2;x++)
	{
		memset(flag,false,sizeof(flag));
		int tmp=x,id=1;len=0;
		while(tmp)
		{
			if(tmp&1){flag[id]=true;cnt[len++]=id;}
			tmp>>=1;
			id++;
		}
		int res=0;
		for(int i=0;i<len;i++)
		{
			for(int j=1;j<=n;j++)
				if(!flag[j])res+=num[cnt[i]][j];
		}
		//cout<<x<<' '<<res<<endl;
		if(res>ans)ans=res;
	}
	printf("%d\n",ans);
	return 0;
}

Gym - 102056I

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
bool used[110][110];
int a,b,c;
typedef struct node
{
	int l,r;
	int res[50000];
	int len;
}N;
queue<N>num;
void print(N ans)
{
	cout<<ans.len<<endl;
	for(int i=0;i<ans.len;i++)
	{
		switch(ans.res[i])
		{
			case 1: printf("FILL(1)\n");break;
			case 2: printf("FILL(2)\n");break;
			case 3: printf("DROP(1)\n");break;
			case 4: printf("DROP(2)\n");break;
			case 5: printf("POUR(1,2)\n");break;
			case 6: printf("POUR(2,1)\n");break;
		}
	}
}
int main()
{
	scanf("%d%d%d",&a,&b,&c);
	for(int i=0;i<=a;i++)
		for(int j=0;j<=b;j++)
			used[i][j]=false;
	N t;
	t.l=0;t.r=0;t.len=0;num.push(t);
	used[0][0]=true;
	while(!num.empty())
	{
		N now=num.front();
		num.pop();
		if(now.l==c||now.r==c)
		{
			print(now);
			return 0;
		}
		if(now.l!=a&&!used[a][now.r])
		{
			N next;
			next.l=a;
			next.r=now.r;
			next.len=now.len+1;
			for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
			next.res[next.len-1]=1;
			used[a][now.r]=true;
			num.push(next);
		}
		if(now.r!=b&&!used[now.l][b])
		{
			N next;
			next.l=now.l;
			next.r=b;
			next.len=now.len+1;
			for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
			next.res[next.len-1]=2;
			used[now.l][b]=true;
			num.push(next);
		}
		if(now.l!=0&&!used[0][now.r])
		{
			N next;
			next.l=0;
			next.r=now.r;
			next.len=now.len+1;
			for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
			next.res[next.len-1]=3;
			used[0][now.r]=true;
			num.push(next);
		}
		if(now.r!=0&&!used[now.l][0])
		{
			N next;
			next.l=now.l;
			next.r=0;
			next.len=now.len+1;
			for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
			next.res[next.len-1]=4;
			used[now.l][0]=true;
			num.push(next);
		}
		if(now.l!=0&&now.r!=b)
		{
			int l,r;
			if(now.l>=b-now.r)
			{
				r=b;
				l=now.l-b+now.r;
			}
			else
			{
				l=0;
				r=now.r+now.l;
			}
			if(!used[l][r])
			{
				N next;
				next.l=l;
				next.r=r;
				next.len=now.len+1;
				for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
				next.res[next.len-1]=5;
				used[l][r]=true;
				num.push(next);
			}
		}
		if(now.l!=a&&now.r!=0)
		{
			//cout<<now.l<<' '<<now.r<<endl;
			int l,r;
			if(now.r>=a-now.l)
			{
				l=a;
				r=now.r-a+now.l;
				//cout<<l<<' '<<r<<endl;
			}
			else
			{
				r=0;
				l=now.l+now.r;
				//cout<<l<<' '<<r<<endl;
			}
			if(!used[l][r])
			{
				//cout<<l<<' '<<r<<endl;
				N next;
				next.l=l;
				next.r=r;
				next.len=now.len+1;
				for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
				next.res[next.len-1]=6;
				used[l][r]=true;
				num.push(next);
			}
		}
	}
	printf("impossible\n");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值