Возьмите сокровище из подземного дворца
У короля X есть сокровищница подземных дворцов. Матрица сеток размером nxm. В каждую сетку поместите ребенка. К каждому ребенку прикреплен ценник.
Вход в подземный дворец находится в верхнем левом углу, а выход - в правом нижнем углу.
Сяо Мина отвели ко входу в подземный дворец, и король попросил его пройти вправо или вниз.
При прохождении через сетку, если ценность сокровища в этой сетке выше, чем ценность любого сокровища в руках Сяо Мин, Сяо Мин может поднять его (конечно, вам не нужно брать его).
Когда Сяо Мин идет к выходу, если сокровищ в его руке оказывается k штук, эти сокровища можно отдать Сяо Миню.
Пожалуйста, помогите Сяоминю подсчитать, сколько различных планов действий у него есть, чтобы получить эти k сокровищ в той или иной ситуации.
[Формат данных]
Введите 3 целых числа в строку, разделенных пробелами: nmk (1 <= n, m <= 50, 1 <= k <= 12)
Затем есть n строк данных, и каждая строка содержит m целых чисел. Ci (0 <= Ci <= 12) представляет собой стоимость сокровища в этой сетке.
Требуется вывести целое число, что означает, что количество планов действий для k сокровищ принято. Это число может быть очень большим и вывести результат по модулю 1000000007.
Например, ввод:
2 2 2
1 2
2 1
Программа должна выводить:
2
Другой пример, ввод:
2 3 2
1 2 3
2 1 5
Программа должна выводить:
14
Соглашение о ресурсах:
Пиковое потребление памяти
<256 МБ Потребление ЦП <1000 мс
Пожалуйста, строго следуйте выводам запроса, не печатайте лишний контент, например: «Пожалуйста, введите ...».
Все коды помещаются в один исходный файл.После завершения отладки скопируйте и отправьте исходный код.
Примечание. Функция main должна возвращать 0.
Примечание. Используйте только стандарты ANSI C / ANSI C ++ и не вызывайте специальные функции, которые зависят от среды компиляции или операционной системы.
Примечание. Все зависимые функции должны быть явно #include <xxx> в исходном файле. Общие файлы заголовков не могут быть пропущены в настройках проекта.
При отправке обратите внимание на выбор желаемого типа компилятора.
Анализ проблемы
Глубокий поиск + рекурсия + по модулю
Рекурсивная величина изменения - это каждая координата, текущее максимальное значение и значение k (количество);
Рекурсивный вызов, когда текущее значение ребенка больше, чем максимальное значение, вы можете выполнить рекурсию вниз или вправо и изменить текущее максимальное значение на текущее, а количество изменений ребенка будет +1. Если оно не превышает текущего максимального значения, то идите прямо вниз или вправо, и количество элементов не изменится;
Рекурсивный выход, когда координата достигает границы, она может быть возвращена. Если левая сторона настроена на последнюю сетку, тогда необходимо учитывать количество детских изменений. Если количество дочерних изменений достигает предела в это время, затем вернитесь напрямую.Если он не достигнут и значение меньше 1, вы можете продолжить, вы можете +1 результат и затем вернуться.
Обратите внимание, что в вопросе говорится, что результат может быть очень большим, поэтому он сохраняется в longlong, а указанное число берется по модулю при возврате.
#include <iostream>
using namespace std;
//深搜+递归+取模
int n, m, k;
int data[50][50];
long long res;
const int MOD = 1000000007;
void dfs(int x, int y, int max, int count){
if(x == n || y == m){
return ;
}
int cur = data[x][y];
if(x == n-1 && y == m-1){
if(count == k || (count == k-1 && cur > max)){
res ++;
if(res > MOD){
res %= MOD;
}
}
}
if(cur > max){
dfs(x, y+1, cur, count+1);
dfs(x+1, y, cur, count+1);
}
dfs(x, y+1, max, count);
dfs(x+1, y, max, count);
}
int main(int argc, char** argv) {
cin >> n >> m >> k;
for(int i = 0; i < n; i ++){
for(int j = 0; j < m; j++){
cin >> data[i][j];
}
}
dfs(0, 0, -1, 0); //第一个点的价值为0;
cout << res << endl;
return 0;
}