f[i][j][p][c]表示走到坐标为i,j时,拿了p件物品,最大价值为c的方案数量
由题意对选择和不选择当前物品的情况进行累加即可
需要注意的是,所有的DP问题都需要考虑如何进行状态的初始化,即其他所有的状态是从哪一个有效状态转移过来的,在这里即为在原点时选和不选的两种情况,所以初始化:
f[1][1][0][0] = 1
f[1][1][1][a[1][1]] = 1
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,k;
const int mod=1000000007;
const int N=55,M=13;
typedef long long ll;
//坐标x,y 物品数 最大价值
ll f[N][N][M+2][M+2];
int a[55][55];
void dp()
{
f[1][1][0][0] = 1;
f[1][1][1][a[1][1]] = 1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int p=0;p<=k;p++)
for(int c=0;c<=M;c++)
{
//不取
f[i][j][p][c]+=(f[i-1][j][p][c]%mod);
f[i][j][p][c]%=mod;
f[i][j][p][c]+=(f[i][j-1][p][c]%mod);
f[i][j][p][c]%=mod;
//取
if(c==a[i][j]&&p>0)
for(int s=0;s<a[i][j];s++)
{
f[i][j][p][c]+=(f[i-1][j][p-1][s]%mod);
f[i][j][p][c]%=mod;
f[i][j][p][c]+=(f[i][j-1][p-1][s]%mod);
f[i][j][p][c]%=mod;
}
}
}
void solve()
{
ll res=0;
for(int i=1;i<=M;i++)
{
res+=f[n][m][k][i]%mod;
res%=mod;
}
cout<<res<<endl;
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];;
a[i][j]++;//把价值为0的改为价值为1的
}
dp();
solve();
}