题目链接
思路:考虑递推 f[i][j][a][b]表示,表示第 i,j个宝藏选了 a个,其中最大是 b的方案数。
每个宝藏都有两种,选或者不选。
初始条件为: f[1][1][0][0]=f[1][1][1][a[1][1]]=1
不选: f[i][j][x][p]+=f[i−1][j][x][p]+f[i][j−1][x][p]
选: f[i][j][x][a[i][j]]+=f[i−1][j][x−1][p]+f[i][j−1][x−1][p],p<a[i][j]
注意处理一下细节即可。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
const int N = 2e5 +11;
const LL mod=1e9+7;
LL f[55][55][14][14],n,m,k,a[100][100];//第i行第j个选a个最大是b的方案,f[i][j][a][b]
int main(){
ios::sync_with_stdio(false);
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]++;
f[1][1][1][a[1][1]]=1;
f[1][1][0][0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1&&j==1)continue;
for(int x=0;x<=k;x++){
for(int p=0;p<=13;p++)f[i][j][x][p]+=f[i-1][j][x][p]+f[i][j-1][x][p],f[i][j][x][p]%=mod;
if(x>=1)for(int p=0;p<a[i][j];p++)f[i][j][x][a[i][j]]+=f[i-1][j][x-1][p]+f[i][j-1][x-1][p];
f[i][j][x][a[i][j]]%=mod;
}
}
}
LL ans=0;
for(int i=1;i<=13;i++)ans+=f[n][m][k][i],ans%=mod;
cout<<ans<<endl;
return 0;
}