方法一:
暴力dfs深搜,但是这种方法超时,但是想法比较简单。
#include<iostream>
using namespace std;
int arr[51][51];
bool haven[51][51];
int times = 0;
int dx[2] = { 1,0 };
int dy[2] = { 0,1 };
int n, m, k;
bool better(int u)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (haven[i][j])
{
if (arr[i][j] >= u)
return false;
}
}
}
return true;
}
void dfs(int u, int v, int own)
{
if (u > n || v > m || own>k)
{
return;
}
//
if (u == n && v == m && own == k)
{
times++;
times = times % 1000000007;
return;
}
//
for (int i = 0; i < 2; i++)
{
int tx = u + dx[i];
int ty = v + dy[i];
if (tx <= n && ty <= m)
{
if (better(arr[tx][ty]))
{
haven[tx][ty] = true;
dfs(tx, ty, own + 1);
haven[tx][ty] = false;
}
dfs(tx, ty, own);
}
}
}
int main()
{
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> arr[i][j];
}
}
haven[1][1] = 1;
dfs(1, 1, 1);
haven[1][1] = 0;
dfs(1, 1, 0);
cout << times;
}
方法二:
结合动态规划的深搜(正解),如何理解四维数组很关键。
我们把一维看作一条线,二维是一张纸,三维是一本书,那四维就是书架。
#include<iostream>
using namespace std;
#define M 1000000007
int arr[51][51];
int dp[51][51][15][15];
int n, m, k;
int moven[2][2] = { {1,0},{0,1} };
int dfs(int x, int y, int cur, int maxv)
{
if (dp[x][y][cur][maxv + 1] != -1)
return dp[x][y][cur][maxv + 1];
if (x == n && y == m)
{
if (cur == k || (cur == k - 1 && maxv < arr[x][y]))
{
return dp[x][y][cur][maxv + 1] = 1;
}
else
{
return dp[x][y][cur][maxv + 1] = 0;
}
}
long long s = 0;
for (int i = 0; i < 2; i++)
{
int tx = x + moven[i][0];
int ty = y + moven[i][1];
if (tx <= n && ty <= m)
{
if (maxv < arr[x][y])
{
s += dfs(tx, ty, cur + 1, arr[x][y]);
}
s += dfs(tx, ty, cur, maxv);
}
}
return dp[x][y][cur][maxv + 1] = s % M;
}
int main()
{
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
cin >> arr[i][j];
}
}
memset(dp, -1, sizeof(dp));
dfs(1, 1, 0, -1);
cout << dp[1][1][0][0];
}