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;
}
今天的内容非常简单,但我不能放松,努力学好没一个知识点,做到会做的不做错,成为更好的自己

浙公网安备 33010602011771号