Thinking Process
初始点是(m,1),终点是(1,n)。终点的最后一个状态只能从(1,n-1)或者(2,n)这两个坐标得来。对(i,j)这个坐标来说,由于题目只允许向上或者是向下走,所以f[i][j]=f[i][j-1]+f[i+1][j]
。状态方程自然得到。
NOTICE
- 此题不可以使用递归来做。会超时
- 数组方面要开大一点,m和n都是3000的数据范围
- 得开long long
- 得取余 【一开始做的时候没取余搞得结果错了】
Code
#include<iostream>
using namespace std;
typedef long long ll;
int m, n;
int map[3010][3010];
int vis[3010][3010];
ll f[3010][3010];
template<class T>inline void read(T &res)
{
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
ll calc(int i, int j){
if(i < 1 || j < 1 || map[i][j] == 1 || i > m || j > n) return 0;
if(f[i][j]) return f[i][j];
return f[i][j] = (calc(i, j - 1) + calc(i + 1, j)) % 2333;
}
int main() {
read(m), read(n);
for(int i = 1; i <= m;i ++ ) {
for(int j = 1;j <= n; j ++ ) {
read(map[i][j]);
}
}
f[m][1] = 1;
for(int i = m; i >= 1; i --) {
for(int j = 1; j <= n; j ++) {
if(i < 1 || j < 1 || map[i][j] == 1 || i > m || j > n) f[i][j] = 0;
if(map[i][j - 1] != 1) f[i][j] += f[i][j - 1];
if(map[i + 1][j] != 1) f[i][j] += f[i + 1][j];
f[i][j] %= 2333;
}
}
cout << f[1][n];
}