7月4日学习总结

今天学习了搜索的优化,感觉是这几天里最简单的一次了。
搜索分为深搜(DFS)和广搜(BFS),深搜的目的是算是否可以到达货求方案数,例如Addition Chains这道题,需要枚举前面所有的数去相加,正常做肯定是要超时的别问我怎么知道的,所以我们需要剪枝,如果枚举的长度已经等于之前算出的最小长度了,就直接结束,开始下一次枚举,具体代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int read() {
  int x;
  cin>>x;
  return x;
}
int n,x[1145140]={0,1},y[1145140],ans=1e18; 
bool vis[114][114];
void dfs(int k,int m)
{
  if(m==ans) return ;
  if(k>=n)
  {
  	if(k==n&&m<ans)
  	{
  		ans=m;
  		for(int i=1;i<=m;i++) y[i]=x[i];
  	}
  	return ;
  }
  for(int i=m;i>=1;i--)
  {
  	for(int j=i;j>=1;j--)
  	{
  		if(x[i]+x[j]<=x[m]) vis[i][j]=1;
  		else vis[i][j]=0;
  		if(!vis[i][j])
  		{
  			vis[i][j]=1;
  			x[m+1]=x[i]+x[j];
  			dfs(x[m+1],m+1);
  			vis[i][j]=0;
  		}
  	}
  }
}
signed main() {
  while(cin>>n)
  {
  	if(!n) return 0;
  	ans=1e18;
  	dfs(1,1);
  	for(int i=1;i<=ans;i++) cout<<y[i]<<' ';
  	cout<<endl;
  }
  return 0;
}

下午的广搜则是求最短路径,例如打开灯泡 Switch the Lamp On这道题,需要记录每一个去过的点,避免重复进入,由于我迷人的方向感,导致我代码写对,但枚举的方向坐标写错,查了一个小时,最后画了个图才写对,也是卡了我好长时间,下面是正确代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int read() {
	int x;
	cin>>x;
	return x;
}
deque<pair<int,int> >o;
int n,m,ans;
bool x[1145][1145],vis[1145][1145];
int dx[4]= {-1,1,1,-1};
int dy[4]= {1,1,-1,-1};
signed main() {
//	freopen("jie.in","r",stdin);
//	freopen("jie.out","w",stdout);
	n=read(),m=read();
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++) {
			char a;
			cin>>a;
			if(a=='\\') x[i][j]=1;
			else x[i][j]=0;
		}
	}
	o.push_back({0,0});
	o.push_back({-1,-1});
	while(!o.empty()) {
		int a=o.front().first,b=o.front().second;
		o.pop_front();
		if(a==-1&&b==-1) {
			if(o.empty()) break;
			ans++;
			o.push_back({-1,-1});
			continue;
		}
		vis[a][b]=1;
		if(a==n&&b==m) {
			cout<<ans;
			return 0;
		}
		int t1=a+dx[0],t2=b+dy[0];
		if(t1>=0&&t1<=n&&t2>=0&&t2<=m&&!vis[t1][t2])
		{
			if(x[a][b+1]==0) o.push_front({t1,t2}),vis[t1][t2]=1;
			else o.push_back({t1,t2});
		}
		t1=a+dx[1],t2=b+dy[1];
		if(t1>=0&&t1<=n&&t2>=0&&t2<=m&&!vis[t1][t2])
		{
			if(x[a+1][b+1]==1) o.push_front({t1,t2}),vis[t1][t2]=1;
			else o.push_back({t1,t2});
		}
		t1=a+dx[2],t2=b+dy[2];
		if(t1>=0&&t1<=n&&t2>=0&&t2<=m&&!vis[t1][t2])
		{
			if(x[a+1][b]==0) o.push_front({t1,t2}),vis[t1][t2]=1;
			else o.push_back({t1,t2});
		}
		t1=a+dx[3],t2=b+dy[3];
		if(t1>=0&&t1<=n&&t2>=0&&t2<=m&&!vis[t1][t2])
		{
			if(x[a][b]==1) o.push_front({t1,t2}),vis[t1][t2]=1;
			else o.push_back({t1,t2});
		}
	}
	cout<<"NO SOLUTION";
	return 0;
}

今天的内容非常简单,但我不能放松,努力学好没一个知识点,做到会做的不做错,成为更好的自己

posted @ 2025-07-04 20:46  常益豪  阅读(7)  评论(0)    收藏  举报