블루 브릿지 컵은 이전의 질문은 질문을 지하 궁전의 보물을
문제 설명
X는 왕 지하 궁전 보물이있다. 되고, N × M 개의 격자 매트릭스. 각 그리드는 아기를 넣어. 라벨의 값으로 각 아기 가깝습니다.
상단에있는 지하 궁전 입구는 오른쪽 아래 모서리에 코너 종료를 떠났다.
밥이 지하 궁전의 입구에 찍은, 왕이 오른쪽이나 아래에만 도보로 그에게 물었다.
아기가 어떤 아기 샤오 명나라의 손의 값보다 큰 경우 그리드에 의해 걸었다 그리드 값은 샤오 밍은 (물론, 당신이 취할 수 없음)을 선택할 수 있습니다.
밥은 출구에 갔을 때 그는 아기 K 조각의 손에 될 일 경우, 다음 아기가 밥에게 주어집니다.
도움 샤오 밍은 주어진 상황에서, 그는이 K 보물을 얻을 수있는 행동의 다른 코스의 번호를 가지고, 말하십시오.
입력 포맷
세 정수의 입력 라인이 공백으로 구분 : NMK를 (1 <= N, m <= 50, 1 <= K <= 12)
다음에 n 개의 행은 각 행 갖는 m 정수 CI (0 <= CI <= 거기 12) 의 값의 제곱의 보물을 나타내는
출력 형식을
요구되는 출력 만 K 아기 촬영 동작 프로그램의 수를 나타내는 정수. 이 수는 클 수 있고, 출력은 모듈로 1,000,000,007.
입력 샘플
2 2 2
. 1 2
2 1
샘플 출력
2
입력 샘플
(2) (3) (2)
. (2) 1 3
2 5 1
출력 샘플
(14)
에 대한 깊은 탐구 검색과 첫 번째 시간이 초과 될 수 있도록 대상 첫눈이 얼마나 깊은 검색을 알고있다.
이 질문에 또 하나 개의 제약 조건, 항목의 값이 큰 만의 K 개 선택할 수 있습니다 상품, 픽업 이전보다 따기의 가치
세 가지 측면에서이 주제를.
-
최대 값 항목보다 그리드의 상품의 값이, 다음 선택합니다.
-
최대 값 항목보다 그리드의 상품의 값은, 다음, 선택하지 않은 경우
-
제품 격자의 값은 상품 자체의 최대 값보다 작은 경우, 선택하지 않은
이 범주로 그룹화 될 수 있도록 2.3 이후, 선택되지 않은, 즉 문서 격자를 선택하지 않고, 두 개의된다.
- 항목의 가치 그리드가 상품 자체의 최대 값보다 큰, 다음 선택
- 아니 선택 항목은 격자
다음으로, 나 자신 정지의 조건에 대해 이야기하자
- 경계 (즉 세로축 또는 가로축 = m = N)
- 목적지에 도달하기 위해 (즉, 즉 가로축 = m - 1 종축 = N - 1)
우리가 마지막에 도달하기위한 그래서, 두 가지 상태가있다
- 우리는이 설정되어, 더 이상 선택할 수 k 개의 항목을 집어 플러스 프로그램의 수 있습니다
- 우리는 K 집어 - 1 개 항목 및 끝에있는 상품의 값을 (즉, 오른쪽 하단의 종료 위치)는 선택의 최대 값보다 큽니다. 그런 다음 우리는 기사 위치의 발작도 설정 프로그램, 플러스 프로그램의 번호를 수행 할 수 있습니다.
다음 코드는
#include <iostream>
using namespace std;
#include <algorithm>
int n, m, k, a[55][55];
long long sum = 0;
#define MAX_SIZE 1000000007
void dfs(int x, int y, int max, int t)//x->横坐标 y->纵坐标 max->捡到的物品最大值, t->捡到的物品的数量
{
if (x == n || y == m)
{
return ;//中止条件1
}
if (x == n - 1 && y == m - 1) //中止条件2
{
if (t == k)//终点状态条件1
{
sum++;
sum %= MAX_SIZE;
}
if (t == k - 1 && a[x][y] > max)//终点状态条件2
{
sum++;
sum %= MAX_SIZE;
}
}
if (a[x][y] > max)
{
dfs(x + 1, y, a[x][y], t + 1);//深搜能够进行的条件1
dfs(x, y + 1, a[x][y], t + 1);
}
dfs(x + 1, y, max, t);//深搜能够进行的条件2
dfs(x, y + 1, max, t);
}
int main()
{
int i, j;
cin >> n >> m >> k;
for (i = 0 ; i < n ; i++)
{
for (j = 0 ; j < m ; j++)
{
cin >> a[i][j];
}
}
dfs(0, 0, -1, 0);//因为输入的价值可能等于0,所以传入-1
cout << sum % MAX_SIZE;;
}
물론, 깊은 탐색 시간 제한 ·····
후 메모리 어레이, 즉 메모리 [X] [Y] [이용 맥스] [t], 메모리를 들어.
그렇다면 위의 절차를 개선하기 위해?
- 공극 형은 공지 된 방법의 원 전화 번호에 직접 동작 할 수 있으므로 긴 긴 메모리 어레이를 사용한다.
- 돌려 주어, 장소의 반환 값은 변경
- 계산 이미 저장 값
- 어떤 값을 가지고 직접 적용 할 수 있습니다
- 이전 전역 변수의 합이 취소
이 장소에 대한 이야기는 변환 프로세스의 자세한 사항
- 몇 가지 예는 응답하거나 해결책은, 그래서 모든 메모리는 피하기 혼란 결과를 얻을하거나 초기화되는, -1로 초기화되지 않습니다
- 우리가 최대 = 위에 통과하기 때문에 -1, 현재 우리가 들어 가지 배열 도달 이번에 능숙 할 것이 가능 배열 인덱스가 오버플 -1 그러나 우리는 -1과 비교되어야 할 더 처리되도록, 즉, 최대 플러스 배열의 하나의 처리.
#include <iostream>
using namespace std;
#include <cstring>
#include <algorithm>
int n, m, k, a[55][55];
#define MAX_SIZE 1000000007
long long memory[55][55][15][15];
long long dfs(int x, int y, int max, int t)//x->横坐标 y->纵坐标 max->捡到的物品最大值, t->捡到的物品的数量
{
long long sum = 0;
if (memory[x][y][max + 1][t] != -1)
{
return memory[x][y][max + 1][t];
}
if (x == n || y == m)
{
return 0;
}
if (x == n - 1 && y == m - 1)
{
if (t == k)
{
sum++;
}
if (t == k - 1 && a[x][y] > max)
{
sum++;
}
sum %= MAX_SIZE;
return sum;
}
if (a[x][y] > max)
{
sum += dfs(x + 1, y, a[x][y], t + 1);
sum += dfs(x, y + 1, a[x][y], t + 1);
}
sum += dfs(x + 1, y, max, t);
sum += dfs(x, y + 1, max, t);
memory[x][y][max + 1][t] = sum % MAX_SIZE;
return sum % MAX_SIZE;
}
int main()
{
int i, j;
cin >> n >> m >> k;
for (i = 0 ; i < n ; i++)
{
for (j = 0 ; j < m ; j++)
{
cin >> a[i][j];
}
}
memset(memory, -1, sizeof(memory));
printf("%lld", dfs(0, 0, -1, 0));
}
잘못된 만약, 문제가 밖으로 포인트! 시청 해 주셔서 감사합니다!