小记:我利用前面的值来更新当前值的方法 硬是想不通哪里错了,只能用向后的了
思路:每格最大值为20,
我们对每个值 更新其所能到达的位置的值, 保存的是放法数
那么时间复杂度就是O(n*m*20*20) 1s内是可以的
code :
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define REP(a,b,c) for(int a = b; a < c; ++a) #define eps 10e-8 const int MAX_ = 110; const int N = 1010; const int INF = 0x7fffffff; const int M = 10000; int dp[MAX_][MAX_]; int p[MAX_][MAX_]; int main(){ int n, m, ans; int T; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); REP(j, 1, n+1){ REP(i, 1, m+1){ scanf("%d", &p[j][i]); } } REP(k, 0, n+1)REP(i, 0, m+1) dp[k][i] = 0; dp[1][1] = 1; REP(i, 1, n+1){ REP(j, 1, m+1){ //if(i == 1 && j == 1)continue; dp[i][j] %= M; for(int k = i; k <= p[i][j] + i && k <= n; ++k){ for(int r = j; r <= p[i][j] + j && r <= m; ++r){ if(k == i && r == j) continue; if(p[i][j] >= k + r - i - j) dp[k][r] += dp[i][j]; } } //printf("%d ", dp[i][j]); } //printf("\n"); } dp[n][m] %= M; printf("%d\n", dp[n][m]); } return 0; }