题目链接:
https://www.luogu.org/problemnew/show/P1373
题意理解
首先,由于是要找所有的解总数,因此显然是不能暴力检查每条路径的吧。。。然后再换一个思路,好像是可以考虑用深搜+递推记录数量。但是这样的话,好像是可以直接拿循环来写。然后再改改好像就成了dp?
dp[i][j][k][l] d p [ i ] [ j ] [ k ] [ l ] 表示在 (i,j) ( i , j ) 处,第 l l 个人走完后,差值为的情况。
然后我按照这种写法写了之后,发现应该是T掉了6个点,我感觉应该是因为Java太慢了,于是决定改成C++试一下。
然后显然,是因为Java太慢了,改成C++之后,直接过掉了。
我的代码
不能过掉全部样例的Java代码。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int n, m, k;
static int MOD = 1000000007;
static int[][][][] dp;
public static void main(String[] args) {
FastScanner fs = new FastScanner();
n = fs.nextInt();
m = fs.nextInt();
k = fs.nextInt();
k++;
dp = new int[n][m][k][2];
int[][] nums = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
nums[i][j] = fs.nextInt();
dp[i][j][nums[i][j] % k][0] = 1;
}
}
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int t = 0; t < k; t++) {
if (i - 1 >= 0) {
dp[i][j][t][1] = (dp[i - 1][j][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD;
dp[i][j][t][0] = (dp[i - 1][j][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD;
}
if (j - 1 >= 0) {
dp[i][j][t][1] = (dp[i][j - 1][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD;
dp[i][j][t][0] = (dp[i][j - 1][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD;
}
}
res = (res + dp[i][j][0][1]) % MOD;
}
}
System.out.println(res);
}
public static class FastScanner {
StringTokenizer st;
BufferedReader br;
private void eat(String s) {
st = new StringTokenizer(s);
}
public FastScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
eat("");
}
public String nextLine() {
try {
return br.readLine();
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
public boolean hasNext() {
while (!st.hasMoreTokens()) {
String s = nextLine();
if (s == null) {
return false;
}
eat(s);
}
return true;
}
public String nextToken() {
hasNext();
return st.nextToken();
}
public int nextInt() {
return Integer.valueOf(nextToken());
}
}
}
改写之后的C++代码。
#include<stdio.h>
void read(int &x) {
x = 0;
int f = 1;
char ch = getchar();
while(ch > '9'||ch < '0') {
if(ch == '-') {
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + (int)(ch - 48);
ch = getchar();
}
x = x * f;
}
int n, m, k;
const int MOD = 1000000007;
const int maxn = 805;
int dp[maxn][maxn][17][2];
int nums[maxn][maxn];
int main() {
read(n);
read(m);
read(k);
k++;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
read(nums[i][j]);
dp[i][j][nums[i][j] % k][0] = 1;
}
}
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int t = 0; t < k; t++) {
if (i - 1 >= 0) {
dp[i][j][t][1] = (dp[i - 1][j][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD;
dp[i][j][t][0] = (dp[i - 1][j][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD;
}
if (j - 1 >= 0) {
dp[i][j][t][1] = (dp[i][j - 1][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD;
dp[i][j][t][0] = (dp[i][j - 1][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD;
}
}
res = (res + dp[i][j][0][1]) % MOD;
}
}
printf("%d", res);
return 0;
}