洛谷1006 传纸条

笑着哭i 提交于 2020-03-24 08:00:50

3 月,跳不动了?>>>

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

棋盘dp,化双向为单向:视作从左上往右下传两张纸条且路劲不重复。
又由于只能向右或向下传递,所以两张纸条过程中必定处于同一斜线上,即横纵坐标之和相等。这样就得到了降维的关键。
用dp[s][i][j]表示纸条1走到第i行,纸条2走到第j行时的最大好心程度,那么方程也不难推得了。

#include <cstdio>
#include <algorithm>
#define N 51
using namespace std;

int a[N][N], dp[N * 2][N][N];

int main(void)
{

    int i, j, s, m, n, tmp;
    scanf("%d%d", &m, &n);
    for (i = 1; i <= m; ++i)
        for (j = 1; j <= n; ++j)
            scanf("%d", &a[i][j]);
    for (s = 3; s <= m + n; ++s)
        for (i = 1; i <= min(s - 1, m); ++i)
            for (j = 1; j <= min(s - 1, m); ++j){
                if (i == j) tmp = a[i][s - i];
                else tmp = a[i][s - i] + a[j][s - j];
                dp[s][i][j] = max(dp[s][i][j], dp[s - 1][i - 1][j - 1]);
                dp[s][i][j] = max(dp[s][i][j], dp[s - 1][i][j]);
                dp[s][i][j] = max(dp[s][i][j], dp[s - 1][i - 1][j]);
                dp[s][i][j] = max(dp[s][i][j], dp[s - 1][i][j - 1]);
                dp[s][i][j] += tmp;
            }
    printf("%d\n", dp[m + n][m][m]);
    return 0;
}
发布了98 篇原创文章 · 获赞 7 · 访问量 2万+
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!