51Nod 1084 矩阵取数问题

来源:互联网 发布:大闸蟹 二恶英 知乎 编辑:程序博客网 时间:2024/05/20 19:47

这里写图片描述

思路:

之前遇到过一道题, 问从左上到右下最大是多少,走法是一样的。而这道题是
相当于走两边,那么该怎么走?
如果直接走两遍相同的地方只加一次,那么答案是错的,因为有可能是交叉走。
所以我们选择直接让两个人直接走。dp变成了三维的利用行和列的关系既可。
dp[step][i][j]表示step步第一个人在i行第二个人在j行。

分为两种情况

  • i == j 时只能加一次
  • i != j 时候可以加两个不同的数字

注意:

循环条件一定要结合step 和 行和列的关系
走到一个位置有四种情况

#include <iostream>#include <cstdio>using namespace std;const int maxn = 205;int n,m,a[maxn][maxn];int dp[maxn*2][maxn][maxn];int main(){    //freopen("in.txt","r",stdin);    scanf("%d%d",&m,&n);    for(int i = 1;i <= n; i++) {        for(int j = 1;j <= m; j++) {            scanf("%d",&a[i][j]);        }    }    for(int step = 1;step <= n+m; step++) {        for(int i = 1;i <= n && step - i >= 0; i++) {            for(int j = 1;j <= n && step - j >= 0; j++) {                if(i == j) {                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j-1]+a[i][step-i]);                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j]+a[i][step-i]);                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j-1]+a[i][step-i]);                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j]+a[i][step-i]);                }                else {                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j-1]+a[i][step-i]+a[j][step-j]);                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j]+a[i][step-i]+a[j][step-j]);                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j-1]+a[i][step-i]+a[j][step-j]);                    dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j]+a[i][step-i]+a[j][step-j]);                }            }        }    }    printf("%d\n",dp[m+n][n][n]);    return 0;}
原创粉丝点击