地宫取宝
X 国王有一个地宫宝库,是 n×m 个格子的矩阵,每个格子放一件宝贝,每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是 k 件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这 k 件宝贝。
输入格式
第一行 3 个整数,n,m,k,含义见题目描述。
接下来 n 行,每行有 m 个整数 Ci 用来描述宝库矩阵每个格子的宝贝价值。
输出格式
输出一个整数,表示正好取 k 个宝贝的行动方案数。
该数字可能很大,输出它对 1000000007 取模的结果。
数据范围
1≤n,m≤50,
1≤k≤12,
0≤Ci≤12
输入样例1:
2 2 2
1 2
2 1
输出样例1:
2
输入样例2:
2 3 2
1 2 3
2 1 5
输出样例2:
14
参考这篇文章
分析:
动态规划:
状态表示: dp[i][j][cnt][mx]:从(i,j)位置出发,现有物品数量为cnt,现有物品的最大价值为mx时的方案数。
状态计算: 在(i,j)这个点,存在两种选择方式:
①.a[i][j]<mx:(i,j)点的物品价值小于现在已有物品的最大价值,肯定不能拿,此时,方案数量为:不选这个位置的物品向右走的方案数加上向下走的方案数:
dp[i][j][cnt][mx] = dp[i][j+1][cnt][mx] + dp[i+1][j][cnt][mx];
②.a[i][j]>mx:该位置的物品价值大于现有物品的最大价值,可以选择拿或者不拿,此时方案数为:选这个位置的物品向下走和向右走的和不选这个位置的物品向下或者向右走的方案数:
dp[i][j][t][mx] = dp[i][j + 1][t + 1][a[i][j]] + //选这个位置的物品向右走和向下走的方案数
dp[i + 1][j][t + 1][a[i][j]] +
dp[i][j + 1][t][mx] + //不选这个位置的物品向右或向下走的方案数
dp[i + 1][j][t][mx]
边界条件: 在(n,m)终点位置,如果已经拿够了k个物品,不管现有物品的最大价值是多少,最终都只有1个方案(不选这个位置的物品,因为已经选够了)。
dp[n][m][k][i] = 1; // i = [0,13]
且如果在终点时选了 k-1 个物品且刚好终点位置的物品可以选,则也只有1种方案(选这个位置的):
dp[n][m][k - 1][i] = 1
注意: 本题存在物品价值为0的情况,所以在起始状态什么都没拿的时候将现有最大价值表示为-1,但是在数组中不存在-1的情况,所以统一将所有物品的价值都+1。
#include<iostream>
#include<algorithm>
#include<cstring>