洛谷 1736 创意吃鱼法

这是一道来自洛谷普及训练场的题目。

第一眼看到此题,觉得一个2维DP加一个2维前缀和就ok了,结果72分。。。卡了很久,最后才明白错误的原因。

int calc(int x, int y, int ex, int ey)             //72分 忽略了部分继承的情况 
{
    return s[ex][ey] - s[x - 1][ey] - s[ex][y - 1] + s[x - 1][y - 1];
}

int main() 
{
    n = read();
    m = read();
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
        {
            if (j == 1) b = 0;
            a[i][j] = read();
            b += a[i][j];
            s[i][j] = s[i - 1][j] + b;
        }
    for (int i = 1; i <= m; ++i)
        if (a[1][i]) dp[1][i][0] = dp[1][i][1] = 1;
    for (int i = 2; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
        {
            if (a[i][j] == 0) continue;
            if (dp[i - 1][j - 1][0] && calc(i - dp[i - 1][j - 1][0], j - dp[i - 1][j - 1][0], i, j) == dp[i - 1][j - 1][0] + 1)
                dp[i][j][0] = dp[i - 1][j - 1][0] + 1;
            else dp[i][j][0] = 1;
            if (dp[i - 1][j + 1][1] && calc(i - dp[i - 1][j + 1][1], j, i, j + dp[i - 1][j + 1][1]) == dp[i - 1][j + 1][1] + 1) 
                dp[i][j][1] = dp[i - 1][j + 1][1] + 1;
            else dp[i][j][1] = 1;
            ans = max(ans, max(dp[i][j][0], dp[i][j][1]));
        }
    cout << ans;
}

错误原因是显而易见的,只是我太菜了。。。我们不能只考虑全部继承和全不继承, 我们还要考虑部分继承的情况。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cctype>

using namespace std;

int read()
{
    int x = 0;
    int k = 1;
    char c = getchar();
    while (!isdigit(c))
        if (c == '-') c = getchar(), k = -1;
        else c = getchar();
    while (isdigit(c))
        x = (x << 1) + (x << 3) + (c ^ 48),
        c = getchar();
    return x * k;
}

int n, m, ans = 0, b;
int a[2505][2505];
int dp[2505][2505];
int l[2505][2505];
int u[2505][2505];
int r[2505][2505];

int main()
{
    n = read();
    m = read();
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
        {
            a[i][j] = read();
            if (!a[i][j])
                l[i][j] = l[i][j - 1] + 1,
                u[i][j] = u[i - 1][j] + 1;
            else l[i][j] = u[i][j] = 0, dp[i][j] = min(dp[i - 1][j - 1], min(l[i][j - 1], u[i - 1][j])) + 1, ans = max(dp[i][j], ans);
        }
    memset(dp, 0, sizeof(0));
    for (int i = 1; i <= n; ++i)
        for (int j = m; j >= 1; --j)
            if (!a[i][j])
                r[i][j] = r[i][j + 1] + 1;
            else r[i][j] = 0, dp[i][j] = min(dp[i - 1][j + 1], min(r[i][j + 1], u[i - 1][j])) + 1, ans = max(dp[i][j], ans);
    cout << ans;
}

 

posted @ 2018-10-09 07:30  Christopher_Yan  阅读(172)  评论(0编辑  收藏  举报