DFS初级剪枝及心得
关于DFS心得:
1、利用结构体,记录mark和题目要求的基本属性。
2、用到递归,使用递归时注意要设置出口,即符合要求时return,注意对递归的理解,对于不同情况可能要传递不同的参数,但出口都是一样的。
3、在DFS时可以剪枝,即对明显不符合条件的情况(基本判断,比如正方形的四边一样长,三角形的两边大于第三边)直接排除,不参与递归,在剪枝的时候注意正确的剪枝。所以在DFS超时时可以考虑剪枝。
4、在递归发现不符合条件需要返回上一层的时候,要将不符合条件的元素flag消除(DFS、BFS的区别之一)。
例题:
Problem Description
Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?
Input
The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick - an integer between 1 and 10,000.
Output
For each case, output a line containing “yes” if is is possible to form a square; otherwise output “no”.
Sample Input
3
4 1 1 1 1
5 11 20 30 40 50
8 1 7 2 6 4 4 3 5
.
Sample Output
yes
no
yes
大神滴代码。。。。。。。。。。。。
//剪支62MSAC
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int n,cnt,sum;
struct node
{
int lenth;
int mark;
}stick[25];
int cmp(node a,node b)
{
return a.lenth>b.lenth;
}
int dfs(int len,int count,int l,int pos)
{
if(count==4)return 1;
for(int i=pos;i<n;i++)
{
if(stick[i].mark)continue;
if(len==(stick[i].lenth+l))
{
stick[i].mark=1;
if(dfs(len,count+1,0,0))
return 1;
stick[i].mark=0;
return 0;
}
else if(len>(stick[i].lenth+l))
{
stick[i].mark=1;
l+=stick[i].lenth;
if(dfs(len,count,l,i+1))
return 1;
l-=stick[i].lenth;
stick[i].mark=0;
if(l==0) return 0;
while(stick[i].lenth==stick[i+1].lenth)i++;
}
}
return 0;
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d",&n);
cnt=sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&stick[i].lenth);
sum+=stick[i].lenth;
stick[i].mark=0;
}
sort(stick,stick+n,cmp);
if(sum%4||n<4)
{
cout<<"no"<<endl;
continue;
}
cnt=sum/4;
if(dfs(cnt,0,0,0))
{
cout<<"yes"<<endl;
}
else
{
cout<<"no"<<endl;
}
}
return 0;
}
#include <iostream>
#include <algorithm>
using namespace std;
int n,s,k,a[22],visit[22]={0};? //a数组用来记录那一组数据,visit数组用来记录当前组的数据是否可用
void DFS(int sum,int x,int d)? //sum是当前计算的和,等于正方形边长的话就配好了一条边了,x是记录当前配好了多少条边,d是上一次匹配到了哪里,是剪枝的关键
{
if(k||x==3)? //当配上了三边的时候就说明能构成正方形了,如果已经能配成正方形就直接返回了
{
k=1;return;? //k=1标记已经能够成正方形了
}
int i;
for(i=d;i<n;i++)? //从上次断点开始匹配
{
if(k)return;? //已经构成正方形就直接返回
if(!visit[i])? //询问这第i组数据是否可用
if(sum+a[i]==s)? //如果正好配成边
{
visit[i]=1;
DFS(0,x+1,0);? //初始化s和d并已经配成的边+1
visit[i]=0;
}
else if(sum+a[i]<s)? //如果比边小
{
visit[i]=1;
DFS(sum+a[i],x,i+1);? //传送断点和此时的值
visit[i]=0;
}
}
}
bool cmp(int a,int b)
{
return a<b;
}
int main(void)
{
int m,i;
cin>>m;
while(m--&&cin>>n)
{
for(i=s=0;i<n;i++)
cin>>a[i],s+=a[i];? //统计正方形周长
sort(a,a+n,cmp);? //从小到大排序
if(s%4==0)? //判断周长是否是正方形的形式
{
s/=4;? //s变成记录正方形的边长
k=0;? //初始化k
DFS(0,0,0);? //和为0,已配成的边数量为0,断点是起点
if(k)cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
else cout<<"no"<<endl;
}
return 0;
}
DFS初级剪枝及心得的更多相关文章
- hdoj--1010<dfs+奇偶剪枝>
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目描述:在n*m的矩阵中,有一起点和终点,中间有墙,给出起点终点和墙,并给出步数,在该步数情况 ...
- hdu1010 Tempter of the Bone —— dfs+奇偶性剪枝
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 Tempter of the Bone Time Limit: 2000/1000 MS (Ja ...
- HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意: 输入 n m t,生成 n*m 矩阵,矩阵元素由 ‘.’ 'S' 'D' 'X' 四 ...
- hdu.1010.Tempter of the Bone(dfs+奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- hdu 1728:逃离迷宫(DFS,剪枝)
逃离迷宫 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- hdu 1010:Tempter of the Bone(DFS + 奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- [HDOJ5952]Counting Cliques(DFS,剪枝)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5952 题意:求图中规模为s的团的个数. DFS+剪枝,姿势不好很容易TLE啊. #include &l ...
- hdu - 1010 Tempter of the Bone (dfs+奇偶性剪枝) && hdu-1015 Safecracker(简单搜索)
http://acm.hdu.edu.cn/showproblem.php?pid=1010 这题就是问能不能在t时刻走到门口,不能用bfs的原因大概是可能不一定是最短路路径吧. 但是这题要过除了细心 ...
- hdu-1242 dfs+各种剪枝
思路: 可以和1010一个思路.这个抽象的说就是让你求给定图中两点的最短距离,其实dfs的题目能变化的地方就在“终点的回溯处”,在我们到达终点后,再判断一些附加的值(本题里是最短距离是否更新),从而得 ...
随机推荐
- Python常用模块(二)
一.json与pickle json与pickle模块是为了完成数据的序列化. 序列化是指把对象(变量)从内存中变成可存储或传输的过程,在Python中叫picking,在其他语言中也由其他的叫法,但 ...
- centos7服务器搭建javaweb运行环境及代码部署
之前在一直在学习java web终于写完了第一个小demo,于是在阿里云上买了一个服务器,开始了配置服务器环境的踩坑之旅.... ps:本文不讨论服务器配置的具体步骤,网上都很多,按部就班就是,本文主 ...
- 也谈ThreadLocal
欢迎赐教博客地址(http://www.cnblogs.com/shizhongtao/p/5358411.html) 对于ThreadLocal使用,网上一堆一堆的.什么内存泄露,什么线程不安全.这 ...
- Developer - 如何自我保证Node.js模块质量
组里正在做SaaS产品,其中一些模块(Module)是Node.js实现,这里我们主要使用Node.js实现Web Server来提供服务. 在做SaaS项目之前,组里的开发模式是传统的Deverlo ...
- Java问题定位之Java线程堆栈分析
采用Java开发的大型应用系统越来越大,越来越复杂,很多系统集成在一起,整个系统看起来像个黑盒子.系统运行遭遇问题(系统停止响应,运行越来越慢,或者性能低下,甚至系统宕掉),如何速度命中问题的根本原因 ...
- java compiler没有1.8怎么办
选择第一个点击安装,安装完成后,重启eclipse,打开java compiler 就可以选择1.8了. 成功: 扫个红包吧! Donate捐赠 如果我的文章帮助了你,可以赞赏我 1 元,让我继续写 ...
- 解析UML的面向对象分析与设计
经常听到有朋友抱怨,说学了UML不知该怎么用,或者画了UML却觉得没什么作用.其实,就UML本身来说,它只是一种交流工具,它作为一种标准化交流符号,在OOA&D过程中开发人员间甚至开发人员与客 ...
- April 29 2017 Week 17 Saturday
Every man is a poet when he is in love. 每个恋爱中的人都是诗人. It is said this saying was from Plato, the famo ...
- ffmpeg 安装和参数介绍
0.说明: 1).configure,这一步一般用来生成 Makefile,为下一步的编译做准备,你可以通过在 configure 后加上参数来对安装进行控制,比如代码:./configure –pr ...
- Apache服务器开启gzip压缩的支持
为什么要在服务器上开启压缩?其实,服务器上开启压缩,对整个网站的就是在服务器上把网页的内容压缩后传给客户端,客户端解压后再显示网页的内容.实际就是增加了服务器端和客户端的工作量,减少了网络传输的数据量 ...