NYOJ712

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=712

来看思路:

我们先弱弱的思考一下,首先我们得先从左上角dp到右下角  然后在从右下角dp到左上角

这样就很有难度 我们可以把来回的路径一次dp完事 这样就简单了很多

我们可以设三维数组dp[k][i][j]  k表示第几步,i和j分别表示来回两个点的坐标  那么我们就有状态转移方程

dp[k][i][j] = max(max(dp[k-1][i][j],dp[k-1][i-1][j-1]),max(dp[k-1][i-1][j],dp[k-1][i][j-1]));

下面看代码:

#include<stdio.h>
#include<string.h>
int dp[110][55][55],a[55][55];

int max(int a,int b)
{
    return a > b? a:b;
}

int main()

{
    int N,n,m,t,i,j,k;
    scanf("%d",&N);
    while(N--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&m,&n);
        for(i = 1;i <= m;i++)
        {
            for(j = 1;j <= n;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        for(k = 3;k < m + n;k++)
        {
            for(i = 1;i <= m;i++)
            {
                for(j = i + 1;j <= m;j++)
                {
                    if(k - i < 1||k - j < 1)break;
                    if(i == j)continue;
                    if(k - i > n||k - j > n)continue;
                    dp[k][i][j] = max(max(dp[k-1][i][j],dp[k-1][i-1][j-1]),max(dp[k-1][i-1][j],dp[k-1][i][j-1]));

                    dp[k][i][j] += a[i][k-i] + a[j][k-j];
                }
            }
        }
        int t = m + n;
        dp[t][m][m] = max(max(dp[t-1][m][m],dp[t-1][m-1][m-1]),max(dp[t-1][m-1][m],dp[t-1][m][m-1]));
        printf("%d\n",dp[t][m][m] + a[m][n]);

    }
    return 0;
}
时间: 2024-11-16 22:19:44

NYOJ712的相关文章

浅谈双线程dp (nyoj61 nyoj712)经典【传字条】和【探 寻 宝 藏】

浅谈双线程dp 先看问题: 传纸条(一) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊传到小轩的纸条只可以向下或者向右传递,从小轩