ブルーブリッジカップは、以前の質問が質問に地下宮殿の宝物を取ります

ブルーブリッジカップは、以前の質問が質問に地下宮殿の宝物を取ります

問題の説明
  Xは、王の地下宮殿の宝物を持っています。n×mの格子行列です。各グリッドは、赤ちゃんを置きます。ラベルの値に、それぞれの赤ちゃんに近いです。

上部の地下宮殿の入り口には、右下隅にある出口にコーナーを残しました。

ボブは、地下宮殿の入口に撮影された、王は右または下のみに歩くように頼みました。

グリッド値は、赤ちゃんがどんな赤ちゃん暁明の手の値よりも大きい場合には、暁明は(もちろん、あなたが取ることができない)それを拾うことができ、グリッドによって歩きました。

ボブは、出口に行ったとき、彼は赤ん坊のk個の手の中にあることを起こる場合は、その後、赤ちゃんはボブに与えられます。

してくださいヘルプ暁明は、与えられた状況で、彼はこのk個の宝物を得るために、異なる作用コース数を持っている、と語りました。
入力フォーマットの
  三つの整数の入力ライン、スペースで区切られた:NMK(1 <= N、 M <= 50、1 <= K <= 12)

次いで、N行は、各列を有するm個の整数CI(0 <= CI <=ある 12) の値の二乗の宝物の代表的な
出力フォーマット
  要求出力ちょうどk個の赤ちゃんを取る行動計画の数を表す整数。この数値は大きいかもしれない、その出力は十億七を法。
  
サンプル入力
2 2 2
1 2
2 1

サンプル出力
2

サンプル入力
2 3 2
1 2 3
2 5 1

サンプル出力
14

主題最初の光景がタイムアウトすることがありますどのように深い検索、その程度の深い探索検索で最初に、知っています。
この質問項目の値が大きく、唯一のK枚選ぶことができる1つの以上の制約、品物を拾う前よりオフ摘みの値は、
三つの側面では、このトピックを。

  1. その最大値の項目よりもグリッドでの商品の価値場合は、選択します。

  2. その最大値の項目よりもグリッドの商品の価値は、その後、選択しない場合

  3. 商品グリッドの値は、アイテムそのものの最大値よりも小さい場合には、選択しないでください

    それはカテゴリにグループ化することができるように2.3ので、ために選択されていない、すなわち、物品が格子をピックアップしない、これは、2つになります。


  1. グリッドの価値項目については、商品そのものの最大値よりも大きい場合は、選択し
  2. 項目を選択しない格子

次に、私は彼のサスペンションの条件について話しましょう

  1. 境界(即ち、縦又は横軸= M = N)
  2. 宛先に到達するために(即ち、すなわち、横軸= M - 1または縦= N - 1)

私たちが最後に到達するので、2つの状態があります

  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. void型は、既知の方法の元の数に直接動作することができる限り長い間、メモリアレイを使用します。
  2. 戻ります;場所の戻り値が変更され
  3. 計算既に格納された値のために
  4. いくつかの値を持っているために、直接適用することができます
  5. キャンセル前のグローバル変数の和

この場所についてのトークでは、変換プロセスの詳細

  1. いくつかの例には、混乱を避けるために、そのすべてのメモリが-1に初期化されるまで、解決策を回答していないか、まったく可能性が得られる結果または初期化することです
  2. 我々は最大=の上に渡されたので-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));
}

間違った場合は、トラブルアウトポイント!見ていただきありがとうございます!

おすすめ

転載: blog.csdn.net/qq_44410340/article/details/104971706
おすすめ