• 洛谷 P1004 方格取数


    洛谷 P1004 方格取数

    题目链接:洛谷 P1004 方格取数

    算法标签: 动态规划(DP)

    题目

    题目描述

    设有(N imes N)的方格图((N le 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 imes N)的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的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];
    

    而需要注意的是,由于每个点经过后该点上的数字会清零,所以当两条路径经过同一个点的时候要在总和中减去一个(map[i][j]( == map[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
    ", f[n][n][n][n]);
        return 0;
    }
    
  • 相关阅读:
    Hibernate使用笔记
    svn树冲突的解决方法
    SVN 清理失败的解决方法
    类的实现
    lua元表
    lua中table的常用方法
    C/C++作用域运算符::
    Cocos2d-x Lua 学习
    Lua学习
    吾 三十而望
  • 原文地址:https://www.cnblogs.com/littleseven777/p/11845662.html
Copyright © 2020-2023  润新知