分析:
矩阵里的每一个位置都有标记,要求的问题是:有几种方法能完成这个规定。
那么,我们只需要计算从开始(1,1)到最后(n,m)的深度优先搜索中,有几个是满足要求的即为正确答案。
有个要求是,如果一个格子中的价值比已经拿的都大,那么可以选择拿或者不拿,这里就有两种情况,一个是以手中的最大值mx做标准,另一种是以c[i][j]做标准,两种情况。
代码示例:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 55,p=1e9+7;
int n,m,k,c[N][N];
int dx[]={0,1};
int dy[]={1,0};
int dp[N][N][15][15];
bool inmp(int x,int y){return (x>=1&&x<=n&&y>=1&&y<=m);
}
ll dfs(int x,int y,int mx,int cnt){if(x==n&&y==m)return cnt==k;if(dp[x][y][mx][cnt]!=-1)return dp[x][y][mx][cnt];ll res=0;for(int i=0;i<2;i++){int nx=x+dx[i];int ny=y+dy[i];if(!inmp(nx,ny))continue;// 拿这个 if(c[nx][ny]>mx&&cnt<k)res=(res+dfs(nx,ny,c[nx][ny],cnt+1))%p;// 不拿这个res=(res+dfs(nx,ny,mx,cnt))%p;}return dp[x][y][mx][cnt]=res;
}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);memset(dp,-1,sizeof(dp));cin>>n>>m>>k;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){cin>>c[i][j];c[i][j]++;}cout<<(dfs(1,1,0,0)+dfs(1,1,c[1][1],1))%p;return 0;
}
/*可以设置状态dp[x][y][mx][cnt]表示走到(x,y),手中有cnt个宝贝且最大值为mx的方案数 */