DFS系列 POJ(自认为的讲解)
C - Sum It Up POJ1564
题意:
给你一个N,然后给你一堆数The numbers in each list appear in nonincreasing order, and there may be repetitions.,让你在这对数里找出一些数,如果他们的和sum==N,则按样例的格式数输出。
思路:
那就是DFS呗,深搜一波,当sum==N时就输出,这里有一个就是排除重复的剪枝。为什么呢?
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
#define N 1010
int d[N];
int a[N];
int n,m;
int flag;
void dfs(int num,int sum,int v)
{
if(sum==n)
{
flag=1;
printf("%d",d[0]);
for(int i=1;i<num;i++)
{
printf("+%d",d[i]);
}
printf("\n");
}
if(sum>n)
return;
for(int i=v;i<m;i++)
{
d[num]=a[i];
dfs(num+1,sum+a[i],i+1);
while(a[i]==a[i+1]&&i<m-1) //判重
i++;
}
}
int main()
{
while(~scanf("%d%d",&n,&m)&&n&&m)
{
for(int i=0;i<m;i++)
scanf("%d",&a[i]);
printf("Sums of %d:\n",n);
flag=0;
dfs(0,0,0);
if(!flag)
printf("NONE\n");
}
return 0;
}
D - 迷宫问题 poj3984
题意:中文…
思路:
这道题推荐BFS+手写队列(这是很重要的)+路径输出,路径输出怎么讲解呢?
(某些非正规定义的词语,是本菜鸡自己定义的)
可以自己模拟一下,在一个队列里,我们用当前元素的pre记录上面那个元素在队列里的节点。最开始我们知道是左上角,所以就初始化他的pre值为-1,最后到了终点,就递归输出。
这里用手写队列不仅跑的飞快而且非常省时间。可以感受一下。
那么我们为什么要用STL的queue呢?知道了,请告诉我!谢谢!(学长说用STL简单方便)
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
#define N 1010
struct asd{
int x,y;
int pre; //用来记录路径
};
asd q[25*10];
int head,tail;
int bmap[6][6];
bool vis[6][6];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void shuchu(int x)
{
if(q[x].pre==-1)
{
printf("(%d, %d)\n",q[x].x,q[x].y);
}
else
{
shuchu(q[x].pre);
printf("(%d, %d)\n",q[x].x,q[x].y);
}
}
void bfs()
{
head=0;tail=1;
q[head].x=0;
q[head].y=0;
q[head].pre=-1;
memset(vis,0,sizeof(vis));
vis[0][0]=1;
while(head<tail)
{
int bx,by;
bx=q[head].x;
by=q[head].y;
if(bx==4&&by==4)
{
shuchu(q[head].pre);
return;
}
for(int i=0;i<4;i++)
{
int aa=bx+dx[i];
int bb=by+dy[i];
if(aa<0||bb<0||aa>4||bb>4||vis[aa][bb]||bmap[aa][bb])
continue;
vis[aa][bb]=1;
q[tail].pre=head;
q[tail].x=aa;
q[tail].y=bb;
tail++;
}
head++;
}
}
int main()
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
scanf("%d",&bmap[i][j]);
}
bfs();
printf("(4, 4)\n");
return 0;
}
E – Sticks poj1011
题意:给你一堆棒子,这些棒子是你从一堆一样的棒子折断而来的,现在你忘记了是从那一堆一样的棒子的长度,让你写一个程序,求最短的长度
思路:
讲道理这题的思路,好难讲。
DFS也是非常混乱,剪枝也是.。
与其说是找不到这种所谓的强有力的剪枝,不如说是自己思路不够全面。
其实剪枝就是,尽可能地少去运行不必要的相同条件的路。
好吧,还是来谈谈这道题的体会。
我们可以发现因为all parts became at most 50 units long,而且there are at most 64 sticks,那么原始的长度最长也就是320,那么我们就有理由可以尝试枚举长度,然后去判断是否是最小的长度。
我们可以进行排序,从而大大减少递归次数;(倒序)
为什么是倒序,因为棒子越长的话越不灵活;所以我们是有依据采用倒序的
那么出现一个剪枝:这个满足的长度L,一定满足棒子的总和sum%L==0这个条件。
而且我们还可以想到以判除重复的条件剪枝,即在此刻没有条件的话,就没必要再去对这个相同的棒子去DFS。
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
#define N 70
int len[N];
int n;
int flag,k;
bool vis[N];
void dfs(int v,int sum,int num)
{
if(flag)
return;
if(sum==k)
{
if(num==n)
{
flag=1;
}
else
dfs(0,0,num);
return;
}
if(sum==0)
{
int v=0;
while(vis[v])
v++;
vis[v]=1;
dfs(v+1,len[v],num+1);
vis[v]=0;
return;
}
for(int i=v; i<n; i++)
{
if(sum+len[i]<=k&&!vis[i])
{
if(len[i]==len[i-1]&&!vis[i-1])
continue;
vis[i]=1;
dfs(i+1,sum+len[i],num+1);
vis[i]=0;
}
}
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int sum;
int tmax;
while(~scanf("%d",&n)&&n)
{
sum=0;
tmax=-1;
for(int i=0; i<n; i++)
{
scanf("%d",&len[i]);
if(tmax<len[i])
tmax=len[i];
sum+=len[i];
}
sort(len,len+n,cmp);
for(k=tmax; k<=sum; k++)
{
if(sum%k==0)
{
flag=0;
memset(vis,0,sizeof(vis));
dfs(0,0,0);
if(flag)
{
printf("%d\n",k);
break;
}
}
}
}
return 0;
}
DFS系列 POJ(自认为的讲解)的更多相关文章
- faster-rcnn系列原理介绍及概念讲解
faster-rcnn系列原理介绍及概念讲解 faster-rcnn系列原理介绍及概念讲解2 转:作者:马塔 链接:https://www.zhihu.com/question/42205480/an ...
- Java JUC之Atomic系列12大类实例讲解和原理分解
Java JUC之Atomic系列12大类实例讲解和原理分解 2013-02-21 0个评论 作者:xieyuooo 收藏 我要投稿 在java6以后我们不但接触到了Loc ...
- 【DFS】POJ 1321
POJ 1321 棋盘问题 题意:中文题不解释. 思路:经典DP,比较取巧的想法是一行行(按照题目意思一行最多只能放一个)来看,标记一列列.注意考虑到有些行可能不放的情况. /** Sample In ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- DFS(DP)---POJ 1014(Dividing)
原题目:http://poj.org/problem?id=1014 题目大意: 有分别价值为1,2,3,4,5,6的6种物品,输入6个数字,表示相应价值的物品的数量,问一下能不能将物品分成两份,是两 ...
- 两次DFS,POJ(1481)
题目链接:http://poj.org/problem?id=1481 两次DFS,这里的思路是,没找到*,就说明,有一个骰子,因此,每搜索到一个*,深搜4个方向,并且变为'.',要是搜到'X',就是 ...
- 四色定理+dfs(poj 1129)
题目:Channel Allocation 题意:要求A:BCD,A与B,C,D都不相同,求不同的值,典型的四色定理: #include <iostream> #include <a ...
- DFS(剪枝) POJ 1724 ROADS
题目传送门 题意:问从1到n的最短路径,同时满足花费总值小于等于k 分析:深搜+剪枝,如果之前走过该点或者此时的路劲长度大于最小值就不进行搜索. /************************** ...
- JUC之Atomic系列12大类实例讲解和原理分解
在java6以后我们不但接触到了Lock相关的锁,也接触到了很多更加乐观的原子修改操作,也就是在修改时我们只需要保证它的那个瞬间是安全的即可,经过相应的包装后可以再处理对象的并发修改,以及并发中的AB ...
随机推荐
- Tomcat部署项目时出错java.lang.IllegalStateException: ContainerBase.addChild: start:org.apache.catalina.Life
Tomcat部署项目时出错java.lang.IllegalStateException: ContainerBase.addChild: start:org.apache.catalina.Life ...
- android学习笔记三--Activity 布局
1.线性布局 标签 :<LinearLayout></LinearLayout> 方向:android:orientation, 垂直:vertical 水平:Horizont ...
- Java学习之String StringBuffer StringBuilder区别
1.String:对象长度是不可变的,是线程安全. 2.StringBuffer:对象长度是可变的,是线程安全. 3.StringBuilder:对象长度是可变,不是线程安全.
- sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)
sql server 关于表中只增标识问题 由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...
- VirtualBox中使用双网卡实现CentOS既能上网(校园网)也能使用SSHclient
近期在虚拟机中使用linux操作系统,之前使用NAT方式上网,能够畅通无阻.可是使用SSHclient连接linux虚拟机就必须为其指定固定的IP地址.依照网上的配置方法使用桥接方式,这种方式是能够的 ...
- 【万里征程——Windows App开发】控件大集合1
加入控件的方式有多种.大家更喜欢哪一种呢? 1)使用诸如 Blend for Visual Studio 或 Microsoft Visual Studio XAML 设计器的设计工具. 2)在 Vi ...
- Allegro改动shape网络节点
使用Allegro时改动shape的网络节点方法: ①选择shape->Select Shape or Void/Cavity ②选择要改动的shape ③点击(...)改动网络节点的名字 ④改 ...
- 使用ucontext组件实现的coroutine代码分析
coroutine一般翻译过来就是协程,类似于线程可以切换,而跟线程是由操作系统调度器来实现切换不一样,协程由用户程序自己调度进行切换.我以前也看过协程相关的内容,但没有自己去实现过.最近搞OpenS ...
- 程序设计之另一种读写函数---writev,readv
read()和write()系统调用每次在文件和进程的地址空间之间传送一块连续的数据.但是,应用有时也需要将分散在内存多处地方的数据连续写到文件中,或者反之.在这种情况下,如果要从文件中读一片连续的数 ...
- MVC Controller构造器注入
UnityDependencyResolver 的标准写法 public class UnityDependencyResolver : IDependencyResolver { priva ...