블루 브릿지 컵은 이전의 질문은 질문을 지하 궁전의 보물을

블루 브릿지 컵은 이전의 질문은 질문을 지하 궁전의 보물을

문제 설명
  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 개 선택할 수 있습니다 상품, 픽업 이전보다 따기의 가치
세 가지 측면에서이 주제를.

  1. 최대 값 항목보다 그리드의 상품의 값이, 다음 선택합니다.

  2. 최대 값 항목보다 그리드의 상품의 값은, 다음, 선택하지 않은 경우

  3. 제품 격자의 값은 상품 자체의 최대 값보다 작은 경우, 선택하지 않은

    이 범주로 그룹화 될 수 있도록 2.3 이후, 선택되지 않은, 즉 문서 격자를 선택하지 않고, 두 개의된다.


  1. 항목의 가치 그리드가 상품 자체의 최대 값보다 큰, 다음 선택
  2. 아니 선택 항목은 격자

다음으로, 나 자신 정지의 조건에 대해 이야기하자

  1. 경계 (즉 세로축 또는 가로축 = m = N)
  2. 목적지에 도달하기 위해 (즉, 즉 가로축 = m - 1 종축 = N - 1)

우리가 마지막에 도달하기위한 그래서, 두 가지 상태가있다

  1. 우리는이 설정되어, 더 이상 선택할 수 k 개의 항목을 집어 플러스 프로그램의 수 있습니다
  2. 우리는 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. 공극 형은 공지 된 방법의 원 전화 번호에 직접 동작 할 수 있으므로 긴 긴 메모리 어레이를 사용한다.
  2. 돌려 주어, 장소의 반환 값은 변경
  3. 계산 이미 저장 값
  4. 어떤 값을 가지고 직접 적용 할 수 있습니다
  5. 이전 전역 변수의 합이 취소

이 장소에 대한 이야기는 변환 프로세스의 자세한 사항

  1. 몇 가지 예는 응답하거나 해결책은, 그래서 모든 메모리는 피하기 혼란 결과를 얻을하거나 초기화되는, -1로 초기화되지 않습니다
  2. 우리가 최대 = 위에 통과하기 때문에 -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));
}

잘못된 만약, 문제가 밖으로 포인트! 시청 해 주셔서 감사합니다!

게시 13 개 원래 기사 · 원 찬양 5 · 조회수 489

추천

출처blog.csdn.net/qq_44410340/article/details/104971706