HDU - 1987 How Many Ways (Memoized Search + dp)

Problem Description

This is a simple survival game where you control a robot from the starting point (1,1) of a board to the end point (n,m) of the board. The rules of the game are described as follows:
1. The robot starts at the starting point of the board and has the energy marked at the starting point.
2. The robot can only go right or down, and each step consumes one unit of energy.
3. The robot cannot stay in place.
4. After the robot has chosen a feasible path, when he goes to the end point of this path, he will only have the energy marked by the end point.
write picture description here

As shown in the figure above, the robot starts at (1,1) and has 4 units of energy. The blue square represents the point he can reach, if the end point he chooses in this path selection is (2,4)

point, when he reaches point (2,4) will have 1 unit of energy and start the next path selection until point (6,6) is reached.
Our question is how many ways the robot can get from the beginning to the end. This may be a large number, and the output is modulo 10000.

Input

The first line inputs an integer T, which represents the number of groups of data.
Enter two integers n, m (1 <= n, m <= 100) for the first row of each set of data. Indicates the size of the chessboard. Next, enter n lines, each with m integers e (0 <= e < 20).

Output

The result of modulo 10000 for the total number of output modes for each set of data.

Sample Input

1
6 6
4 5 6 6 4 3
2 2 3 1 7 2
1 1 4 6 2 7
5 8 4 3 9 5
7 6 6 2 1 5
3 1 1 3 7 2

Sample Output

3948

Problem solving ideas:

Memory search.
Initialize dp[n-1][m-1] to 1,
dp[x][y] represents the number of paths from point x, y to the end point and the number
of all paths from x, y to the end point = he The sum of the number of paths from the point to the end point that can be reached currently

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int a[110][110];
int dp[110][110];
int n , m;

int check(int x , int y){
    if(x < 0 || y < 0 || x >= n || y >= m)
        return 0;

    return 1;
}

int dfs(int x , int y){
    int i , j;
    if(dp[x][y] >= 0)
        return dp[x][y];
    dp[x][y] = 0;
    for(i = 0 ; i <= a[x][y] ; i ++)
        for(j = 0 ; j <= a[x][y] - i ; j ++){
            if(check(x + i , y + j) == 0)
                continue;
            if(i + j)   //不能停留在原地
                dp[x][y] = (dp[x][y] + dfs(x + i , y + j)) % 10000;
        }

    return dp[x][y];

}
int main(){
    freopen("D://testData//1978.txt" , "r" , stdin);
    int t ;
    int i , j;
    scanf("%d" , &t);
    while(t --){
        scanf("%d %d",&n , &m);
        memset(a , 0 , sizeof(a));

        for(i = 0 ; i < n ; i ++)
            for(j = 0 ; j < m ; j ++){
                scanf("%d",&a[i][j]);
            }

        memset(dp , -1 , sizeof(dp));

        dp[n-1][m-1] = 1;

        printf("%d\n" ,dfs(0 , 0));


        //输出dp
        /*
        for(i = 0 ; i < n ; i ++){
            for(j = 0 ; j < m ; j ++)
                printf("%d ",dp[i][j]);
            printf("\n");
        }
        */
 /*----------------------------------------------------------------*/
        /*
        用于验证案例:
        2 2
        2 2
        2 1
        时出错。
        从点 (0,0) 到 点(1,1) 应该只有两条路径
        可是输出是三条
        (!!!还是我理解错了!望解答)
        */
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325858337&siteId=291194637