关于剪枝的思考 ——由hdu1010 dfs+剪枝所想到的
来源:互联网 发布:苏州星宇软件 编辑:程序博客网 时间:2024/05/29 16:16
这道题思路不难,就是剪枝要要求很高,否则老是TLE。
dfs+剪枝设计思路:
1,要求的是正好T步到达,不多也不少,所以深度搜索控制的一大条件就是控制步数;
2,对于剪枝,有这么几个点:
(1)步数达到T且成功找到Door的,置success为1,同时完成了本题目的要求,结束本次递归 return,并将success是否为1作为本递归函数的结束条件从而达到剪枝的目的;
(2)步数达到T但没有找到Door的,return;
(3)提前到达了Door,但步数还没到达T的,return;
(4)检测本次递归中距离目标的距离为多少步,记为num,然后计算出还有多少步必须要走,记为k,如果num>k,则必然不能到达,return;如果num<k,说明到达目标绰绰有余,还必须绕圈以消耗掉多余的步数,比如下一个格子就可以到目标了,但是因为规定的步数还大于1必须走完,所以不能直接到Door,必须多绕,这样的话会发现,多绕了一个格子,这个格子就不能再走了,再想到达Door就必须再绕两个其他没走过的格子,相比直接到达就多绕了两个格子,所以要求 (num-k) 必须为大于等于2的偶数(这了大家可以亲自试试),如果不是偶数,return ; 实测发现这是一个很有效的剪枝,可以一举解决TLE的问题,将时间复杂度减小的500ms内。
关于剪枝,要想真正做好,就得深挖题意,找到那些真正能控制时间的因素,尽力把递归层数控制在一个很小的范围内,这说起来容易做起来难,要么就是多做点此类型的题目,自然能熟能生巧,所谓天道酬勤,就是这个意思吧。
下面是代码:
#include<iostream>#include<cstring>#include<cmath>using namespace std;int a[10][10];char b[10];int flag[4][2]={0,-1,0,1,-1,0,1,0};int startx=0;int starty=0;int endx=0;int endy=0; int M=0,N=0,T=0;int success=0;void dfs(int x,int y,int cnt)//cnt为目前(x,y)当前位子的跳数{if(success==1)return ; if( cnt==T && x==endx && y==endy) { success=1; return ; }if(x==endx && y==endy){ return;} if(cnt==T) { return ; } int num=abs(x-endx)+abs(y-endy);//要到达Door此时至少还要走的步数 int k=T-cnt; if(num>k || (k-num)%2!=0)//重要剪枝 return; for(int i=0;i<4;i++) { int p1=x+flag[i][0]; int p2=y+flag[i][1]; if(p1<N && p1>=0 && p2<M && p2>=0 && a[p1][p2]!=0) { a[p1][p2]=0; dfs(p1,p2,cnt+1); a[p1][p2]=1; } } return ;}int main(){ memset(b,'\0',sizeof(b)); memset(a,0,sizeof(a)); while(scanf("%d%d%d",&N,&M,&T)&&( N!=0 && M!=0 && T!=0)) { success=0; int t=N; int i=-1; while(t--){ i++; scanf("%s",b);//gets(b);不要用gets() for(int j=0;j<M;j++) {if(b[j]=='.') a[i][j]=1; else if(b[j]=='S'){ a[i][j]=0; startx=i; starty=j;} else if(b[j]=='D'){ a[i][j]=1; endx=i; endy=j;}elsea[i][j]=0; }memset(b,'\0',sizeof(b));}//输入完毕 dfs(startx,starty,0); if(success)printf("YES\n");elseprintf("NO\n");memset(a,0,sizeof(a)); } return 0;}
- 关于剪枝的思考 ——由hdu1010 dfs+剪枝所想到的
- DFS——HDU1010(经典的奇偶剪枝)
- hdu1010 经典的DFS+奇偶剪枝
- hdu1010 DFS和剪枝
- HDU1010-奇偶剪枝(DFS)
- hdu1010 dfs+路径剪枝
- hdu1010(dfs+剪枝)
- hdu1010 dfs奇偶剪枝
- HDU1010奇偶剪枝DFS
- hdu1010 dfs+剪枝
- HDU1010 DFS+奇偶剪枝
- dfs+剪枝(hdu1010)
- hdu1010 dfs+剪枝
- HDU1010 dfs奇偶剪枝
- HDU1010 DFS+奇偶剪枝
- hdu1010(dfs+剪枝)
- hdu1010(DFS + 奇偶剪枝)
- hdu1010(DFS+奇偶剪枝)
- 一步步学习SPD2010--第九章节--使用可重用工作流和工作流表单(8)--修改InfoPath表单
- oracle数据库软件安装完后在操作系统上的目录结构
- Android学习笔记——关于onConfigurationChanged
- Android高效加载大图多图并有效避免程序OOM
- 关于在manageBean中调用业务方法的问题
- 关于剪枝的思考 ——由hdu1010 dfs+剪枝所想到的
- 因性别歧视,GitHub首位女工程师离开公司
- 点击QQ进行交谈,接口生成地址
- Direct3D固定渲染流水线分析与总结
- 嵌入式系统设计中常用总线和接口
- 产品定价调查
- 2014.3.17 inventory目录 oracle 谷歌
- 学习python的第一天
- 分区表的使用和管理