其他分享
首页 > 其他分享> > 蒜头君的城堡之旅(dp)

蒜头君的城堡之旅(dp)

作者:互联网

题目:

蒜国地域是一个 n 行 m 列的矩阵,下标均从 1 开始。蒜国有个美丽的城堡,在坐标 (n,m) 上,蒜头君在坐标 (1,1) 的位置上。蒜头君打算出发去城堡游玩,游玩结束后返回到起点。在出发去城堡的路上,蒜头君只会选择往下或者往右走,而在返回的路上,蒜头君只会选择往上或者往左走,每次只能走一格。已知每个格子上都有一定数量的蒜味可乐,每个格子至多经过一次。现在蒜头君请你来帮他计算一下,如何计划来回行程,可以收集到最多的蒜味可乐。

输入格式

第一行输入两个整数 n,m(1≤n,m≤50),表示蒜国是一个 n 行 m 列的矩阵。接下来输入 n 行,每行输入 m 个整数,代表一个 n×m 的矩阵,每个整数代表对应位置上的蒜味可乐数量,每行的每两个整数之间用一个空格隔开。其中蒜头君的位置和城堡的位置上没有蒜味可乐,用 0 表示,其余位置上的整数范围在 [1,100] 内。

输出格式

输出一行,输出一个整数,表示蒜头君在来回路上能收集到的蒜味可乐的最大值。

样例输入

3 3

0 2 9

4 8 6

2 7 0

样例输出

36

tap
#include <iostream>
using namespace std;
int map[60][60] = {0}, dp[60][60][60][60] = {0}; //真~四重存在~(其实就是储存了两个点坐标)
int main()
{
    int n, m, x1, x2, y1, y2;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> map[i][j]; //蒜头可乐地图
    for (x1 = 1; x1 <= n; x1++)
    {
        for (y1 = 1; y1 <= m; y1++)
            for (x2 = 1; x2 <= n; x2++)
            {
                y2 = x1 + y1 - x2;    //降低复杂度的玩意儿,避免出现四重循环判断
                if (y2 > m || y2 < 1) //越界,退散
                    continue;
                if (x1 != x2 && y1 != y2) //两人能在同一点
                {
                    dp[x1][y1][x2][y2] = max( 
  max(dp[x1 - 1][y1][x2 - 1][y2], dp[x1][y1 - 1][x2][y2 - 1]),
  max(dp[x1][y1 - 1][x2 - 1][y2], dp[x1 - 1][y1][x2][y2 - 1])) +map[x1][y1] + map[x2][y2];                                
                }  }}//来自上个状态的可乐数(注意每个人都是上一次状态,故每个坐标都有上个状态的调用,故有四个旧态)
    int a;
    a = max(max(dp[n - 1][m][n - 1][m], dp[n - 1][m][n][m - 1]),//到达终点时可能通过终点左边到达,也可能是从终点上方到达
            max(dp[n][m - 1][n - 1][m], dp[n][m - 1][n][m - 1]));
    cout << a;
    return 0;
}
/*先整理一下思路:蒜头往返两次,两次的终点起点相反,且一个格子不能走两次,一个人的往返过程可以等效为两个人都从起点出发,到达同一个终点
并且两人走的格子不能相同,并且两人同步前进(步数也相同),求两人到达终点时取得的最大可乐数(要综合考虑,如果单算单程,不能保证全过程最优)*/
给我搞楞了

标签:蒜头,x1,之旅,x2,y1,y2,dp
来源: https://www.cnblogs.com/emokable/p/16086762.html