小记:我利用前面的值来更新当前值的方法 硬是想不通哪里错了,只能用向后的了
思路:每格最大值为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;
}