藍橋杯2014省賽 《地宮尋寶》100%數據全過代碼

備賽重要, 先放代碼, 題解有時間再寫.

#include<stdio.h>
#include<string.h> 
#define MOD 1000000007
int N = 0;
int M = 0;
int K = 0;
// 存放輸入地圖 
int num[51][51] = {0}; 

// 存放路徑結果 
unsigned long long count_array[51][51] = {0}; 

// 開一個bool 4維數組
// 前兩維表示x, y
// 後面一個表示k值, 用來減少搜索, 
//	如果k已經存在 那麼不用繼續搜索了, 直接+1種情況, 
//  如果不存在就記錄, 並且繼續搜索 
// 最後面一個是當前k值下拿到的最大寶物數 
int cache[51][51][13][13] = {0};


unsigned long long count = 0;
// 直接搜索 
void dfs_1(int n, int x, int y, int max){
	if(x >= M || y >= N) return;
	
	if(num[y][x] > max && n < K){// 可以拿就拿 
		// 剪枝 
		if(n + 1 == K){	// 如果拿起後就夠了 直接加上次數 防止不必要的搜索了 
			count += count_array[y][x];
			count %= MOD;
		}else{
			int temp = max;
			max = num[y][x];
			dfs_1(n + 1, x + 1, y, max);
			dfs_1(n + 1, x, y + 1, max);
			max = temp;
		}
	}
	// 不可以拿, 或者可以拿卻不拿 
	dfs_1(n, x + 1, y, max);
	dfs_1(n, x, y + 1, max);	
	
}
// 記憶式搜索 
long long dfs_4(int n, int x, int y, int max){
	// 限定邊界 
	if(x >= M || y >= N) return 0;
	
	// 查看錶, 如果表已經有數據, 表示正在遍歷一個重複的節點, 直接返回結果 
	if(cache[y][x][n][max] != 0){
		return cache[y][x][n][max];
	} 
	// 注:  爲當前節點所有子節點結果之和
	// 取到和 之後,然後存放進表, 如果以後表裏面有數據, 那麼就可以直接使用 
	long long sum = 0; 
	if(num[y][x] > max && n < K){// 可以拿就拿 
		if(n + 1 == K){	// 如果拿起後就夠了 直接加上次數 防止不必要的搜索了  
			// 這裏是唯一的出口 
			sum += count_array[y][x];
		}else{
			int temp = max;
			max = num[y][x];
			
			sum += dfs_4(n + 1, x + 1, y, max);
			sum %= MOD;
			sum += dfs_4(n + 1, x, y + 1, max);
			sum %= MOD;
			
			max = temp;
		}
	}
	// 不可以拿, 或者可以拿卻不拿 
	sum += dfs_4(n, x + 1, y, max);
	sum %= MOD;
	sum += dfs_4(n, x, y + 1, max);	
	
	cache[y][x][n][max] = sum % MOD;
	return sum % MOD;
}


int main(){
	
	scanf("%d %d %d", &N, &M, &K);
	for(int i= 0; i < N; i++){
		for(int j = 0; j < M; j++){
			scanf("%d", &num[i][j]);
		}
	}// 輸入結束 
	
	// 計算次數矩陣 
	// 用來剪掉 已經找到k件寶物的結果, 使其不再繼續搜索, 直接得出答案 
	count_array[N - 1][M] = 1;
	for(int i = N - 1; i >= 0; --i){
		for(int j = M - 1; j >= 0; --j){
			count_array[i][j]  = count_array[i + 1][j] + count_array[i][j + 1];
			count_array[i][j] %= MOD;
		}
	}
	
	dfs_1(0, 0, 0, 0);
	printf("直接搜索結果: %lld\n", count); 
	// 計算答案 
	long long ans = dfs_4(0, 0, 0, 0);
 
	printf("記憶搜索結果: %lld\n", ans);
	
	return 0;
} 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章