[Dynamic Programming] Adaptation of the problem of crossing the river

Little feather wants to eat spicy strips

Topic background

Xiao Feather and her neighbor have made an appointment to lose weight together, but she wants to eat spicy strips. Unable to resist the temptation of the supermarket in front of her house, Xiao Feather quietly ran out and bought a pack of spicy strips. Xiao Feather who walked out of the supermarket saw his neighbor at a glance.

Feather's home and the supermarket are only separated by a small rectangular square, so she still hopes to run home quickly without being noticed by neighbors.

The neighbor is chatting with people now, so as long as you don't walk too close to the neighbor, the neighbor will not find her. She now wants to know how many ways she can go home without being noticed by her neighbors.

Title description

Taking the position of Feather as the origin, the coordinates of the neighbors and Feather’s home are given. Since Xiao Feather wanted to go home quickly, she only walked down or to the right.

Neighbors and friends were so fascinated to chat. As long as you don't wipe your neighbors and walk by, the neighbors will not find her.

The sample input is shown in the figure below, taking the position of the small feather as the reference (0,0), and her home is at the yellow dot (4,4). The brown dot is the neighbor’s location, the green dot is the neighbor’s side, so you can’t walk

Input format

Two numbers in the first line n, mn, mn,m , represents the location of Xiao Feather's home(n, m) (n, m)(n,m)

Two numbers x, yx, y in the second linex,y , represents the location of the neighbor(x, y) (x, y)(x,and )

Output format

One line, the number of paths that Xiao Feather can walk home smoothly without being noticed by neighbors

Example one

enter

4 4
2 2

Output

4

Prompt description

0 < n , m , x , y ≤ 25 0<n, m, x, y≤25 0<n,m,x,Y2 5 , the position of the small feather is(0, 0) (0,0)(0,0)

answer

Dynamic programming, because Xiao Feather only goes to the right or down, so each position can only come from above or from its left. That is: the number of feasible paths at each position is the sum of the number of feasible paths at the previous position and the left position.

Three steps of dynamic planning :

  1. The original problem: from seeking (0,0)walked (n,m)number of possible paths
  2. Sub-problem: the number of feasible paths from going (0,0)to any point (i,j)in the graph
  3. Use dp[i][j]an array to represent (i, j)the number of feasible paths to go . Transfer equation:dp[i][j] = dp[i-1][j] + dp[i][j-1]

Pay attention to a few details in this question :

  1. The data range is 25, we can ignore the positions that cannot be moved, and estimate the result data range according to the permutation and combination: $C_{50}^{25} = 126410606437752 $ intThe range that has been exceeded (2147483647). But still long longwithin. So our dparray must be opened tolong long
  2. After entering the location of the neighbor, you can take the method of marking in advance. That is, mark all the points that cannot be walked in the map. Then dpcalculate the entire array. But this method requires special judgment in many cases. Also pay attention to the value used for marking and the order of assignment statements, which is more troublesome. Not recommended
  3. Because the map matrix is ​​from the (0,0)beginning to the (n,m)end. If you enter nand mopen the dynamic programming array later, remember to +1, otherwise it will cross the boundary

For specific implementation, it is recommended to judge the first row, the first column and the situation that cannot go directly in dpthe calculation process of the array .

Bidding

#include<bits/stdc++.h>
using namespace std;
int main(){
    
    
	int n,m,x,y,i,j;
	cin>>n>>m>>x>>y;
	long long dp[n+1][m+1];
	//注意加一防止越界,longlong防爆
	dp[1][0]=dp[0][1]=dp[0][0]=1;
	for(i=0;i<=n;i++){
    
    
		for(j=0;j<=m;j++){
    
    
			if(i==x&&j==y-1||i==x&&j==y+1||
			i==x+1&&j==y||i==x-1&&j==y||i==x&&j==y){
    
    
				dp[i][j]=0;			//不可走点,通行条数为0
			}
			else if(0==i&&j)		//第一行
				dp[i][j]=dp[i][j-1];
			else if(0==j&&i)		//第一列
				dp[i][j]=dp[i-1][j];
			else if(i&&j)			//转移方程
				dp[i][j]=dp[i-1][j]+dp[i][j-1];
		}
	}
	cout<<dp[n][m];					//输出走到(n,m)的可行路径数量
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44559752/article/details/107233848