地宫取宝
地宫取宝
$X$ 国王有一个地宫宝库,是 $n \times m$ 个格子的矩阵,每个格子放一件宝贝,每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是 $k$ 件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这 $k$ 件宝贝。
输入格式
第一行 $3$ 个整数,$n$,$m$,$k$,含义见题目描述。
接下来 $n$ 行,每行有 $m$ 个整数 $C_{i}$ 用来描述宝库矩阵每个格子的宝贝价值。
输出格式
输出一个整数,表示正好取 $k$ 个宝贝的行动方案数。
该数字可能很大,输出它对 $1000000007$ 取模的结果。
数据范围
$1 \leq n,m \leq 50$,
$1 \leq k \leq 12$,
$0 \leq C_{i} \leq 12$
输入样例1:
2 2 2 1 2 2 1
输出样例1:
2
输入样例2:
2 3 2 1 2 3 2 1 5
输出样例2:
14
解题思路
可以发现这是一个求集合最大值的问题,可以用动态规划。题目的限制有,每次只能向下或向右走、一定要按照递增的顺序取物品、要恰好取$k$件物品。
dp的维度可以根据这几个限制来确定。首先用$2$维来表示坐标。再用$1$维来表示取的最后一件物品的值,因为物品是按照递增的顺序取的,因此只需要知道最后取的物品大小就可以了。再开一维来表示取了多少件物品。所以dp的维度为$4$维,$f \left( i,j,k,c \right)$。
大概可以知道一共需要$5$重循环,前$4$重循环来枚举$4$个维度,还需要一个循环来进行状态转移计算。大概是一个$50 \times 50 \times 12 \times 13 \times \left( 25 \right)$的计算量。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 const int N = 60, M = 15, mod = 1e9 + 7; 6 7 int graph[N][N], f[N][N][M][M]; 8 9 int main() { 10 int n, m, num; 11 scanf("%d %d %d", &n, &m, &num); 12 for (int i = 1; i <= n; i++) { 13 for (int j = 1; j <= m; j++) { 14 scanf("%d", &graph[i][j]); 15 graph[i][j]++; // c的取值范围变为1~13,因为0用来表示当k为0时取的最后一件物品的价值为0 16 } 17 } 18 19 // 初始化,(1, 1)取一件物品,最后一件物品的价值就是graph[i][j]; (1, 1)不取物品,对应最小的数0 20 f[1][1][1][graph[1][1]] = f[1][1][0][0] = 1; 21 for (int i = 1; i <= n; i++) { 22 for (int j = 1; j <= m; j++) { 23 for (int k = 0; k <= num; k++) { 24 for (int u = 0; u < M; u++) { 25 f[i][j][k][u] = (f[i][j][k][u] + f[i - 1][j][k][u]) % mod; 26 f[i][j][k][u] = (f[i][j][k][u] + f[i][j - 1][k][u]) % mod; 27 if (u == graph[i][j] && k) { // 因为时取得情况,要求k>0,且满足u==graph[i][j] 28 for (int c = 0; c < u; c++) { 29 f[i][j][k][u] = (f[i][j][k][u] + f[i - 1][j][k - 1][c]) % mod; 30 f[i][j][k][u] = (f[i][j][k][u] + f[i][j - 1][k - 1][c]) % mod; 31 } 32 } 33 } 34 } 35 } 36 } 37 38 int ret = 0; 39 for (int i = 1; i < M; i++) { 40 ret = (ret + f[n][m][num][i]) % mod; 41 } 42 printf("%d", ret); 43 44 return 0; 45 }
参考资料
AcWing 1212. 地宫取宝(蓝桥杯C++ AB组辅导课):https://www.acwing.com/video/638/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/15906475.html