简单学习了一下搜索,写了一道关于搜索的题目。
dfs就是一条路走到底,发现没路了,返回来,走另一条路。
bfs就是每条路都走一点,走一点点后就走另一条路了。
BFS:
BFS类似于水波纹的扩散,在求解一些最短路径,最优值问题的时候效率很高。
BFS为了遍历,需要保存所有的状态,对空间来说是一个巨大的消耗。(因为通常是无法递归实现的)
DFS:
DFS主要应用于回溯的搜索问题中,比如迷宫问题,岛屿问题。
DFS能够做到使用一个状态变量去搜索所有的状态空间,这对空间的消耗来说,是非常节约空间的(通常使用递归实现)。
写的那个题主要用到了递归的思想以及简单的dfs,先判断它的边界,也就是判断它结束的条件,如果符合就返回上一步继续搜索下一种方案,循环反复把所有符合的都找出来,就是搜索。
问题 I: 夫子云游
题目描述
改编自猫腻所著的同名小说《将夜》目前正在火热开播,其中男主角宁缺在考书院二层楼时遇一题“那年春,夫子出国游历,遇桃山美酒,遂寻径登山赏桃品酒,一路摘花饮酒而行,始斩一斤桃花,饮一壶酒,后夫子惜酒,故再斩一斤桃花,只饮半壶酒,再斩一斤桃花,饮半半壶酒,如是而行……至山顶,夫子囊中酒尽,惘然四顾,问:夫子一共斩了几斤桃花,饮了几壶酒?”而当我们的男主角宁缺看到这道题目时,更是直接来了句“谁出的这道题,太二了”,紧接着就提笔写下了“夫子饮二壶酒,斩尽满山桃花”后直接就交卷走人了赢得书院弟子的大赞。
今夫子再次游历,他提着酒壶,从出院出来,酒壶中有酒2斗,他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。这一路上,他一共遇到店M(0<M<=10)次,遇到花N(0<M<=10)次,已知最后一次遇到的是花,他正好把酒喝光了。
请计算夫子遇到店和花的合理的次序种数。
可以把遇店记为a,遇花记为b,如果M=5,N=10。则:babaabbabbabbbb 就是合理的次序之一。
输入
M、N 分别为遇到店和花的次数
输出
所有可能店和花次序方案的个数
样例输入 Copy
5 10
样例输出 Copy14
#include<stdio.h>
int N,M,sum;
void dfs(int a,int b,int c) //店花酒
{
if(a==0 && b==1 && c==1)
{
sum++;
return;
}
else
{
if(c<=0 || c>b)
{
return;
}
if(a<M &&a>0)
{
dfs(a-1,b,2*c);
}
if(b<N && b>0)
{
dfs(a,b-1,c-1);
}
}
}
int main()
{
sum=0;
scanf("%d%d",&M,&N);
dfs(M,N,2);
printf("%d\n",sum);
return 0;
}
//有错还没改对,大概思想就是如此
彭哥教了我一下,原本的判断条件a<M,但是刚进入函数时a=M,不可能成立,不会进行下一步的递归。而且a只会减小不会增大不需要判断是否小于M。
改完以后:
#include<stdio.h>
int N,M,sum;
void dfs(int a,int b,int c)
{
//printf("%d %d %d %d\n",a,b,c,sum);
if(a==0 && b==1 && c==1)
{
sum++;
return;
}
else
{
if(c>0 && a>0 && c<=b)
{
dfs(a-1,b,2*c);
}
if(b>0 && c>0 && c<=b)
{
dfs(a,b-1,c-1);
}
}
}
int main()
{
sum=0;
scanf("%d%d",&M,&N);
dfs(M,N,2);
printf("%d\n",sum);
return 0;
}
学习了一点儿dp。
题目1:数字三角形问题
从顶部向下走,每次只能走下面或者右下,走完全程,问你怎么走使得权值最大。
输入:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出:
30
题目链接:NYOJ 18 The Triangle 填表法,普通dp - 西*风 - 博客园
#include<stdio.h>
int max,n,a[2000][2000],b[2000][2000];
//a储存原始三角形信息,b储存最大路径权值的和
int main()
{
int i,j;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
for(j=1; j<=i; j++)
{
scanf("%d",&a[i][j]);
b[i][j] = a[i][j];
}
}
for(i=n-1; i>0; i--) //二维数组最后一行
{
for(j=1; j<=i; j++) //二维数组第一行
{
if(b[i+1][j]>b[i+1][j+1]) //自底向上比较取最大值加和
{
max = b[i+1][j];
}
else
{
max = b[i+1][j+1];
}
b[i][j] += max;
}
}
printf("%d",b[1][1]);
return 0;
}