Depth-First search experience:
Depth-First search type in tree root search:
In the process of using depth-first search,
(1), the most important thing is to talk about the model of the problem:
(2), after modeling, you can find its adjacency point:
(3), starting from a vertex, each using the depth-first template to use flexible changes, you can solve their problems
(4), however, in the problem solving, the solution of the problem is not the optimal solution, time complexity will be very large, the desire, but also need the optimization of pruning:
In the process of depth, is actually a whole enumeration process, but in the use of pruning is to optimize its enumeration, can not enumerate the enumeration, that is, some can make the depth of the process can be stopped directly in the judgment condition; however, the priority pruning will be difficult to think of;
(5), a lot of depth-first search can be used dynamic programming, but the derivation of dynamic programming is difficult to think of;
Describe
There is a grid matrix, and the matrix boundary is infinitely far away. Let us make the following assumptions:
A. Each step, you can only move one block from the current square and walk to an adjacent square;
B. The passing of the lattice immediately collapsed can no longer go the second time;
C. Only go north, east and west in three directions;
Excuse me: If we allow n steps on the grid matrix, how many different schemes are there? 2 ways to go is considered a different scheme as long as there is a difference.
Input
Number of steps allowed to walk on the square n (n <= 20)
Output
Number of scenarios calculated
Sample input
2
Sample output
7
#include <iostream>
using namespace std;
int asp[3][2] = {{0,1},{-1,0},{0,-1}};//denotes East, north, west; search for each direction;
bool mark[100][100];
int DFS (int n,int i,int j)
{
if (n==0)
return 1;
MARK[I][J] = true;
int len_num = 0;
for (int k =0;k<3;k++) {//access for each direction (i.e. each neighbor);
int x = i+asp[k][0];
int y = j+asp[k][1]; cout<< "x==" <<x<< "y==" <<y<<endl;
if (!mark[x][y])
Len_num+=dfs (n-1,x, y); cout << "len_num==" <<len_num<<endl;
}
MARK[I][J] = false;
return len_num;
}
int main ()
{
int N;
cin>>n;
memset (Mark,0,sizeof (Mark));//Initialize the tag array;
cout << DFS (n,50,50) << endl;//arbitrarily enter a point;
return 0;
}
And you can do it with dynamic planning:
In fact, there is a mathematical approach: so that f (n) means the total number of steps to walk N, you can get a recursive
F (n) =f (n−1) +2∗∑k=1n−2f (k)
The next change of type can be obtained
F (n) =f (n−1) +f (n−2) +f (n−2) +2∗∑k=1n−3f (k)
=f (n−1) +f (n−2) +f (n−1) =2∗f (n−1) +f (n−2)
and two boundary conditions
F (1) =3,f (2) =7
Every time you consider the previous direction is to go north, from the next step, it becomes the exact same counting problem, because you can walk in three directions.
If the first step goes north, then the n−1 steps are obviously F (n−1).
If the first step to the east/west, the second step to the north, the next n−2 step is F (n−2), the symmetry of the things to multiply by two.
If the third step goes north, the next n−3 step is F (n−3). And so on
#include <iostream>
using namespace std;
int main ()
{
int n,i;
cin>>n;
int *f=new int[n+1];
F[0]=1;
f[1]=3;
for (i=2;i<=n;i++)
f[i]=f[i-1]+f[i-2]*2+ (f[i-1]-f[i-2]); F[i]=2*f[i-1]+f[i-2];
cout<<f[n]<<endl;
return 0;
}