洛谷 P5307

考虑一个最暴力的 DP,设 fi,j,k 表示走到 (i,j) 乘积为 k 的路径数,显然过不了。

考虑优化一下状态设计,设 fi,j,k 表示走到 (i,j) 还要至少乘上 k 才能不小于 n 的路径数,显然 k 形如 ni 这种形式,至多 O(n) 种,预处理出来离散化后再转移即可。

注意把第一维滚动掉否则会 MLE。

时间复杂度 O(rsn)

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 305, M = 2005, W = 1000005, mod = 1e9 + 7;
int n, m, K;
int a[N][N];
int f[2][N][M];
int val[M], tot, pos[W], b[W];

void add(int &a, int b) { if ((a += b) >= mod) a -= mod; }
int calc(int x, int y) { return x % y == 0 ? x / y : x / y + 1; }

int main() {
	scanf("%d%d%d", &n, &m, &K);
	for (int i = 1; i <= K; ++i) b[i] = calc(K, i);
	for (int i = 1; i <= K; ++i) if (b[i] != b[i - 1]) pos[val[++tot] = b[i]] = tot;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			scanf("%d", &a[i][j]);
	f[1][1][pos[calc(K, a[1][1])]] = 1;
	for (int i = 1; i <= n; ++i) {
		int cur = i & 1, nxt = cur ^ 1;
		for (int j = 1; j <= m; ++j)
			for (int k = 1; k <= tot; ++k) {
				if (j < m) add(f[cur][j + 1][pos[calc(val[k], a[i][j + 1])]], f[cur][j][k]);
				if (i < n) add(f[nxt][j][pos[calc(val[k], a[i + 1][j])]], f[cur][j][k]);
				if (i != n || j != m || k != tot) f[cur][j][k] = 0;
			}
	}
	printf("%d", f[n & 1][m][tot]);
	return 0;
}
posted @   Kobe303  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示