设有 N×N 的方格图,其中某些方格填入正整数,而其它方格填入数字0。某人从左上角 A 出发,可以向下行走,也可以向右行走,直到到达右下角的 B 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。此人从 A 点到 B 点共走了两次,试找出两条这样的路径,使得取得的数字和为最大。

输入格式

  • 第一行为一个整数 N,表示 N×N 的方格图。
  • 接下来的每行有三个整数,第一个为行号数,第二个为列号数,第三个为在该行、该列上所放的数。
  • 行和列编号从 1 开始。
  • 一行“0 0 0”表示结束。

输出格式

输出一个整数,表示两条路径上取得的最大的和。

数据范围

  • N ≤ 10

输入样例

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

输出样例

67

代码实现

#include <iostream>
using namespace std;
const int N = 20;

int n, a, b, c, d, g[N][N], dp[N << 1][N][N];
int main () {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    while(cin >> a >> b >> c, a || b || c) g[a][b] = c;
    for (int k = 2; k <= (n << 1); ++k) {
        for (int i1 = 1; i1 <= n; ++i1) {
            for (int i2 = 1; i2 <= n; ++i2) {
                int j1 = k - i1, j2 = k - i2;
                if (j1 >= 0 && j1 <= n && j2 >= 0 && j2 <= n) {
                    int t = g[i1][j1];
                    if (i1 != i2) t += g[i2][j2];
                    auto& x = dp[k][i1][i2];
                    x = max(x, dp[k - 1][i1 - 1][i2 - 1] + t);
                    x = max(x, dp[k - 1][i1 - 1][i2] + t);
                    x = max(x, dp[k - 1][i1][i2 - 1] + t);
                    x = max(x, dp[k - 1][i1][i2] + t);
                }
            }
        }
    }
    cout << dp[n << 1][n][n];
    return 0;
} 
分类: DP

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

友情链接:Ctips' blog, Colza’s blog

站点状态:Status