[蓝桥杯] Get treasure from the underground palace

King X has a treasure house in the underground palace, which is a matrix of n×m grids. Each grid is placed with a treasure, and each treasure is labeled with a value.

The entrance to the underground palace is in the upper left corner, and the exit is in the lower right corner.

Xiao Ming was taken to the entrance of the underground palace, and the king asked him to walk to the right or down.

When walking through a grid, if the value of the treasure in that grid is greater than that of any treasure in Xiao Ming's hands, Xiao Ming can pick it up (of course, you don't need to take it).

When Xiao Ming walks to the exit, if the treasures in his hand happen to be k pieces, these treasures can be given to Xiao Ming.

Please help Xiaoming calculate how many different action plans he has to obtain these k treasures in a given situation.

Input format The
first line of 3 integers, n, m, k, the meaning is shown in the title description.

In the next n rows, each row has m integers Ci used to describe the treasure value of each grid of the treasure house matrix.

Output format
Output an integer, which means that exactly the number of action plans for k babies is taken.

This number may be very large, and output the result of modulo 1000000007.

Data range
1≤n, m≤50,
1≤k≤12,
0≤Ci≤12
Input example 1:
2 2 2
1 2
2 1
Output example 1:
2
Input example 2:
2 3 2
1 2 3
2 1 5
Output sample 2:
14

Problem-solving ideas:
First, we define dp[i][j][cnt][k] to mean that Xiao Ming walked from the upper left corner to (i, j) and took cnt items with a total value of k. In this problem The value range is (0,12), which means that items at various points on the map may have a value of 0, so when we read in the data, each data is +1, so that the value range becomes (1,13), so that we can consider the initialization problem, and then we think about the relational expression. At this point, we can take it or not. If we don’t take it, the code is as follows:

dp[i][j][cnt][v] = (dp[i][j][cnt][v] + dp[i - 1][j][cnt][v]) % MOD;
dp[i][j][cnt][v] = (dp[i][j][cnt][v] + dp[i][j - 1][cnt][v]) % MOD;

This is to be written separately, and the result is %MOD, otherwise the data will be exploded, and then every time Xiao Ming takes an item larger than the previous item, then, if the item at this point can be retrieved, it must be consistent:
the value of the item at this point is equal to us The value of k in dp[i][j][cnt][k], and if the item is taken, cnt must be greater than 0, and then we have to consider how to initialize. At the starting point, Xiao Ming may or may not take the item This item, so if you don’t take it, dp[1][1][0][0] = 1, take this item dp[1][1][1][w[1][1]]

code show as below:

#include <iostream>
using namespace std;
const int N = 55;
const int MOD = 1000000007;
int dp[N][N][15][15];
int w[N][N];
int n, m, k;

int main() {
    
    
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
    
    
			cin >> w[i][j];
			w[i][j]++;
		}

	dp[1][1][0][0] = 1;
	dp[1][1][1][w[1][1]] = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			for (int cnt = 0; cnt <= k; cnt++)
				for (int v = 0; v <= 13; v++) {
    
    
					dp[i][j][cnt][v] = (dp[i][j][cnt][v] + dp[i - 1][j][cnt][v]) % MOD;
					dp[i][j][cnt][v] = (dp[i][j][cnt][v] + dp[i][j - 1][cnt][v]) % MOD;

					if (cnt > 0 && w[i][j] == v) {
    
    
						for (int s = 0; s < v; s++) {
    
    
							dp[i][j][cnt][v] = (dp[i][j][cnt][v] + dp[i - 1][j][cnt - 1][s]) % MOD;
							dp[i][j][cnt][v] = (dp[i][j][cnt][v] + dp[i][j - 1][cnt - 1][s]) % MOD;

						}
					}
				}

	int res = 0;
	for (int i = 0; i <= 13; i++) {
    
    
		res = (res + dp[n][m][k][i]) % MOD;
	}

	cout << res << endl;
	return 0;

}

Guess you like

Origin blog.csdn.net/m0_51955470/article/details/114421209