羅区P1004は、いくつかの正方形を取ります
トピックリンク:羅区P1004は、いくつかの正方形を取ります
アルゴリズムタグ: 动态规划(DP)
タイトル
タイトル説明
(N \回N \)\正方形図\((N \ル9)\) 、前記他のボックス番号0に配置されている間、我々は、いくつかの正の整数を満たすグリッド。下に示すように(実施例参照)に示します。
A
0 0 0 0 0 0 0 0
0 0 13 0 0 6 0 0
0 0 0 0 7 0 0 0
0 0 0 14 0 0 0 0
0 21 0 0 0 4 0 0
0 0 15 0 0 0 0 0
0 14 0 0 0 0 0 0
0 0 0 0 0 0 0 0
B
グラフの左上隅からの誰か(\ A)\ビューのポイントは、あなたがの右下隅に達するまで、あなたはまた、右に行くことができ、歩くことができます\(B \)ポイント。(除去は数が0になっチェッカー後)を介して、途中で、彼は正方形の数を削除することができます。
人\(A \)点\(B \)倍ダウン上の点は、数の最大和が得られるように、そのような経路2を見つけることを試みます。
入力形式
整数第行為入力(N \)\(で表されるN \回N \)(\図四角)、各ラインは次の3つの整数を有しているが、位置のための第3の数、最初の二つの位置を示します数の上に置きます。0は、単一のライン入力の終了を示します。
出力フォーマット
出力のみ得られた2つのパスと最大値を表す整数。
サンプル入力と出力
入力#1
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
出力#1
67
ソリューション:
データ対象なぜなら四次元動的プログラミング、\(N≤9 \)は次のようにので、タイムアウトまたはハイパー約ない心配を行い、特定の伝達方程式は、次のとおり
f[i][j][k][l] = max{
// i,k描述两条路径横坐标情况
// j,l描述两条路径纵坐标情况
f[i - 1][j][k - 1][l],
f[i][j - 1][k][l - 1],
f[i - 1][j][k][l - 1],
f[i][j - 1][k - 1][l])
}+ map[i][j] + map[k][l];
この点上の各点の後の数字がクリアされるので、時間的に同じ点を通る2つのパスが加算減算するようとき、その一方に留意されたい\(マップ[I] [J ](=を=マップ[K] [L] )\) この点について数は一度だけ計算することができることを確実にします。
また、読み取りに注意を払うための時間でwhile()
終了条件を。
ACコード
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 10;
int n, map[N][N], f[N][N][N][N];
int getmax(int a, int b, int c, int d)
{
int ans = max(a, max(b, max(c, d)));
return ans;
}
int main()
{
scanf("%d", &n);
int x, y, z;
while(1)
{
scanf("%d%d%d", &x, &y, &z);
if (x == 0 && y == 0 && z == 0)
break;
map[x][y] = z;
}
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
for (int k = 1; k <= n; k ++ )
for (int l = 1; l <= n; l ++ )
{
f[i][j][k][l] =
getmax(f[i - 1][j][k - 1][l],
f[i][j - 1][k][l - 1],
f[i - 1][j][k][l - 1],
f[i][j - 1][k - 1][l])
+ map[i][j] + map[k][l];
if (i == k && j == l)
f[i][j][k][l] -= map[i][j];
}
printf("%d\n", f[n][n][n][n]);
return 0;
}