[ブルーブリッジカップ] Zhenti Training 2014 C ++ Aグループ質問8:地下宮殿から宝物を取り出す

地下の宮殿から宝物を取りなさい

X王には地下宮殿の宝庫があります。nxmグリッドの行列です。各グリッドに赤ちゃんを置きます。各赤ちゃんには値ラベルが貼られています。
地下宮殿への入り口は左上隅にあり、出口は右下隅にあります。
シャオミンは地下宮殿の入り口に連れて行かれ、王は彼に右または下に歩くように頼みました。
グリッドを歩くとき、そのグリッドの宝物の価値がシャオミンの手にあるどの宝物の価値よりも大きい場合、シャオミンはそれを拾うことができます(もちろん、あなたはそれを取る必要はありません)。
シャオミンが出口まで歩いたとき、彼の手にある宝物がたまたまk個だった場合、これらの宝物をシャオミンに渡すことができます。
Xiaomingが特定の状況でこれらのk個の宝物を入手するために必要なさまざまな行動計画の数を計算するのを手伝ってください。
[データ形式]
スペースで区切って3つの整数を1行に入力します。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
リソース規則:
ピークメモリ消費量<256MCPU
消費量<1000ms
リクエストの出力に厳密に従ってください。「入力してください...」などの余分なコンテンツを過剰に印刷しないでください。
すべてのコードは同じソースファイルに配置されます。デバッグに合格したら、ソースコードをコピーして送信します。
注: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;
}

 

おすすめ

転載: blog.csdn.net/weixin_44566432/article/details/115263878