您的位置:首页 > 产品设计 > UI/UE

提高历练地 动态规划TG.lv(1) 小a和uim之大逃离

2018-03-08 15:27 260 查看
题目链接:

https://www.luogu.org/problemnew/show/P1373

题意理解

首先,由于是要找所有的解总数,因此显然是不能暴力检查每条路径的吧。。。然后再换一个思路,好像是可以考虑用深搜+递推记录数量。但是这样的话,好像是可以直接拿循环来写。然后再改改好像就成了dp?

dp[i][j][k][l]dp[i][j][k][l] 表示在(i,j)(i,j)处,第ll个人走完后,差值为kk的情况。

然后我按照这种写法写了之后,发现应该是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
[m][k][2];
int[][] nums = new int
[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: