「 HDU 1978 」 How many ways

# 解题思路

记忆化搜索

一个点可以跳到的点,取决于它现在的能量。而且有一个显而易见的性质就是一条可行路径的终点和起点的横坐标之差加上纵坐标之差肯定小于等于起点的能量。

因为跳到一个点之后,能量和之前的点就已经没有关系了,只与现在的点有关,所以不需要传递能量到下一层。

嗯,思路就是酱紫的

# 附上代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int HA = 1e4;
inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while (c <= '9' && c >= '0') {x = x*10 + c-'0'; c = getchar();}
    return x * f;
}
int T, n, m, en[103][103], f[103][103];
bool vis[103][103];
inline int dfs(int x, int y) {
    if(x > n || y > m || x < 1 || y < 1) return 0;
    if(x == n && y == m) return 1;
    if(vis[x][y] != false) return f[x][y];
    for(int i=0; i<=en[x][y]; i++) {
        for(int j=0; j+i<=en[x][y]; j++) {
            int xx = i + x, yy = j + y;
            if(xx == x && yy == y) continue;
            f[x][y] += dfs(xx, yy);
            if(f[x][y] >= HA) f[x][y] %= HA;
        }
    }
    vis[x][y] = true;
    return f[x][y];
}
int main() {
    T = read();
    while (T--) {
        memset(vis, 0, sizeof(vis));
        memset(f, 0, sizeof(f));
        n = read(), m = read();
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                en[i][j] = read();
        printf("%d\n", dfs(1, 1) % HA);
    }
}

猜你喜欢

转载自www.cnblogs.com/bljfy/p/9638452.html