[NOIP 2008] 传纸条

[题目链接]

          https://www.luogu.org/problemnew/show/P1006

[算法]

        设现在两条路径的前i步已确定,第一条路径的最后一步在(x1,y1),第二条路径的最后一步在(x2,y2),则有 :

        x1 + y1 = x2 + y2 = i + 2

        因此,当i,x1,x2确定时,这5个值就都确定了

        用f[i][x1][x2]表示现在两条路径都走了i步,第1条路径的最后一步的x坐标为x1,第二条路径的最后一步的x坐标为x2,dp即可

[代码]

       

#include<bits/stdc++.h>
using namespace std;
#define MAXN 55

int i,j,k,m,n,p,q;
int a[MAXN][MAXN];
int f[MAXN<<1][MAXN][MAXN];

inline bool valid(int x,int y)
{
    return x >= 1 && x <= m && y >= 1 && y <= n;
}

int main()
{
    
    scanf("%d%d",&m,&n);
    for (i = 1; i <= m; i++)
    {
        for (j = 1; j <= n; j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    f[0][1][1] = a[1][1];
    for (i = 0; i <= m + n - 2; i++)
    {
        for (j = 1; j <= m; j++)
        {
            for (k = 1; k <= m; k++)
            {
                p = i + 2 - j;
                q = i + 2 - k;
                if (valid(j,p) && valid(k,q))
                {
                    if (j == k && p + 1 == q + 1) f[i+1][j][k] = max(f[i+1][j][k],f[i][j][k] + a[j][p+1]);
                    else f[i+1][j][k] = max(f[i+1][j][k],f[i][j][k] + a[j][p+1] + a[k][q+1]);
                    if (j + 1 == k + 1 && p == q) f[i+1][j+1][k+1] = max(f[i+1][j+1][k+1],f[i][j][k] + a[j+1][p]);
                    else f[i+1][j+1][k+1] = max(f[i+1][j+1][k+1],f[i][j][k] + a[j+1][p] + a[k+1][q]);
                    if (j == k + 1 && p + 1 == q) f[i+1][j][k+1] = max(f[i+1][j][k+1],f[i][j][k] + a[j][p+1]);
                    else f[i+1][j][k+1] = max(f[i+1][j][k+1],f[i][j][k] + a[j][p+1] + a[k+1][q]);
                    if (j + 1 == k && p == q + 1) f[i+1][j+1][k] = max(f[i+1][j+1][k],f[i][j][k] + a[j+1][p]);
                    else f[i+1][j+1][k] = max(f[i+1][j+1][k],f[i][j][k] + a[j+1][p] + a[k][q+1]);
                }
            }
        }
    }
    printf("%d\n",f[m+n-2][m][m]);

    return 0;
}

 

posted @ 2018-07-17 20:09  evenbao  阅读(119)  评论(0编辑  收藏  举报