DFS及其优化

DFS及其优化

[优化剪枝]
1.优化搜索顺序
先搜索节点少的分支,如果搜进来一个大分支而答案不在此分支就会浪费大量时间。
2.可行性剪枝
如果当前分支不可行就退出剪枝。
3.最优性剪枝
如果当前搜索到的答案已经比搜过的答案差了,就退出当前剪枝。
即如果此分支确定不是最优解(差于已有解)就 return
4.记忆化搜索(=排除等效冗余)
记录之前搜过 Data ,避免重复搜。
例题:
1.accoders的【一本通基础搜索与回溯】红与黑1862
思路:一个简单的dfs,但是n和m的输入是反的!!!
code:
#include<bits/stdc++.h>
using namespace std;
char a[50][50];
int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1},vis[50][50];
int n,m,sum=0;
int dfs(int x,int y){
for(int i=1;i<=4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx>0&&xx<=m&&yy>0&&yy<=n&&a[xx][yy]=='.'&&!vis[xx][yy]){
sum++;
vis[xx][yy]=1;
dfs(xx,yy);
}
}
return sum;
}
int main(){
while(1){
cin>>n>>m;
if(n==0&&m==0){
return 0;
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
int sx,sy;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(a[i][j]=='@'){
sx=i,sy=j;
}
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
vis[i][j]=0;
}
}
sum=1;
vis[sx][sy]=1;
cout<<dfs(sx,sy)<<"\n";
}
return 0;
}
2.
accoders【一本通基础搜索与回溯】马走日1865
思路:
边界是0~n-10~m-1!!!
code:
#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,vis[10][10];
int dx[10]={0,2,2,1,-1,-2,-2,1,-1},dy[10]={0,1,-1,2,2,1,-1,-2,-2};
int ans=0,tot;
void dfs(int nx,int ny,int now){
if(tot==now){
ans++;
return;
}
for(int i=1;i<=8;i++){
int xx=nx+dx[i],yy=ny+dy[i];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]){
vis[xx][yy]=1;
dfs(xx,yy,now+1);
vis[xx][yy]=0;
}
}
}
int main(){
int T;
cin>>T;
while(T--){
ans=0;
cin>>n>>m>>x>>y;
// memset(vis,0,sizeof(vis));
tot=n*m;
vis[x][y]=1;
ans=0;
dfs(x,y,1);
vis[x][y]=0;
cout<<ans<<"\n";
}
return 0;
}
3.
accoders 【算法进阶 搜索深度优先搜索】小猫爬山
luogu P10483 小猫爬山
思路:
从大到小排,能塞就塞,不能就新开。
code:
#include<bits/stdc++.h>
using namespace std;
int a[101],sum[101];
int n,w;
int cmp(int x,int y){
return x>y;
}
int ans;
void dfs(int u,int k){
if(k>=ans)return;
if(u==n){
ans=k;
return ;
}
for(int i=0;i<k;i++){
if(sum[i]+a[u]<=w){
sum[i]+=a[u];
dfs(u+1,k);
sum[i]-=a[u];
}
}
sum[k]=a[u];
dfs(u+1,k+1);
sum[k]=0;
}
int main(){
cin>>n>>w;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n,cmp);
ans=n;
dfs(0,0);
cout<<ans;
return 0;
}
4.
luogu P1784 数独
思路:
一个判断行,列,小方格内有没有重复数字的dfs
code:
#include<bits/stdc++.h>
using namespace std;
int h[11][11],l[11][11],g[11][11],sd[11][11];
void go_out(){
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
cout<<sd[i][j]<<" ";
}
cout<<"\n";
}
exit(0);
}
void dfs(int x,int y){
if(sd[x][y]!=0){
if(x==9&&y==9){
go_out();
}else if(y==9){
dfs(x+1,1);
}else{
dfs(x,y+1);
}
}else{
for(int i=1;i<=9;i++){
if(!h[x][i]&&!l[y][i]&&!g[(x-1)/3*3+(y-1)/3+1][i]){
sd[x][y]=i;
h[x][i]=l[y][i]=g[(x-1)/3*3+(y-1)/3+1][i]=1;
if(x==9&&y==9){
go_out();
}else if(y==9){
dfs(x+1,1);
}else{
dfs(x,y+1);
}
h[x][i]=l[y][i]=g[(x-1)/3*3+(y-1)/3+1][i]=0;
sd[x][y]=0;
}
}
}
}
int main(){
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
int t;
cin>>t;
if(t!=0){
h[i][t]=l[j][t]=g[(i-1)/3*3+(j-1)/3+1][t]=1;
}
sd[i][j]=t;
}
}
dfs(1,1);
return 0;
}
posted @   lbh123  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示