zoukankan      html  css  js  c++  java
  • 题解 P1736 【创意吃鱼法】

    主要思路:二维DP + 二维前缀和

    我就讲讲我当时做这道题的想法就好了。如果你只拿了部分分,可以看看修改和优化方法。

    一开始我没看清题,一看,,,这不就是求最长的对角线吗(当时我还只以为是左上右下方向的对角线),,,好求啊,,,简单的dp就好啦

    当这个点有鱼时(a[i][j] == 1),最大的长度就是其左上的那个点的最大值+1,如果没鱼,就为0。

    if(a[i][j] == 1)
    	f[i][j] = f[i - 1][j - 1] + 1;
    else
    	f[i][j] = 0;
    

    然后去找所有之中的最大值

    但是,显然不对。

    后来我又看到了是整个正方形里就只有一条对角线上有鱼,突然想到最大正方形的前缀和做法。相似的,我们用前缀和算出这个正方形的和为对角线的值,不就只有对角线了?

    WA了很多,下了一组数据看了看,发现左下右上的对角线也可以,我就把刚刚的操作按左右颠倒重新做了一遍。

    还是不对。

    为什么?因为我们找的是之中的最大值,如果最大值那个被正方形的那个条件约束住了,就不会寻找比他次大却符合条件的那个答案了。

    如果听不懂的话可以对比下我在最后统计答案的代码

    正确:

    go(i, 1, n, 1)
            go(j, 1, m, 1){
                while (sum1[i][j] - sum1[i - ooo][j] - sum1[i][j - ooo] + sum1[i - ooo][j - ooo] != f[i][j])
                    f[i][j]--;
                        maxx = max(maxx, f[i][j]);}
    

    错误

        go(i, 1, n, 1)
            go(j, 1, m, 1) 
                if (sum1[i][j] - sum1[i - ooo][j] - sum1[i][j - ooo] + sum1[i - ooo][j - ooo] == f[i][j])
                    maxx = max(maxx, f[i][j]);
    

    这样代码是对的,不过那个while真的是烦,我们还得在dp完以后再去找合适的正方形,很浪费时间。

    所以,我们可以在dp时就加上正方形的约束条件。

        go(i, 1, n, 1)
            go(j, 1, m, 1) 
                if (a[i][j] && sum1[i][j] - sum1[i - oo][j] - sum1[i][j - oo] + sum1[i - oo][j - oo] == f[i - 1][j - 1])
                    f[i][j] = f[i - 1][j - 1] + 1;
                        else 
                            f[i][j] = 0;
    

    若部分代码看不懂请到文末代码处寻找define,,,

    这样就OK了。

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <set>
    #include <stack>
    #include <string>
    #include <vector>
    using namespace std;
    #define go(i, j, n, k) for (int i = j; i <= n; i += k)
    #define fo(i, j, n, k) for (int i = j; i >= n; i -= k)
    #define rep(i, x) for (int i = h[x]; i; i = e[i].nxt)
    #define mn 2511
    #define inf 2147483647
    #define ll long long
    #define ld long double
    #define fi first
    #define se second
    #define root 1, n, 1
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    #define bson l, r, rt
    //#define LOCAL
    #define mod 
    #define Debug(...) fprintf(stderr, __VA_ARGS__)
    inline int read(){
        int f = 1, x = 0;char ch = getchar();
        while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
        while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    //This is AC head above...
    int n, m, a[mn][mn], f[mn][mn], sum1[mn][mn], sum2[mn][mn],g[mn][mn], maxx = -1;
    #define ooo f[i][j]
    #define ppp g[i][j]
    inline void debug(){
        go(i, 1, n, 1)
            go(j, 1, m, 1)
                printf("%d%c", f[i][j], (j == m ? '
    ' : ' '));
        puts("");
        go(i, 1, n, 1)
            go(j, 1, m, 1)
                printf("%d%c", g[i][j], (j == m ? '
    ' : ' '));
    }
    int main(){
        n = read(), m = read();
        go(i, 1, n, 1)
            go(j, 1, m, 1)
                a[i][j] = read();
        go(i, 1, n, 1)
            go(j, 1, m, 1)
                sum1[i][j] = sum1[i - 1][j] + sum1[i][j - 1] - sum1[i - 1][j - 1] + a[i][j];
        go(i, 1, n, 1)
            go(j, 1, m, 1) 
                if (a[i][j])
                    f[i][j] = f[i - 1][j - 1] + 1;
                        else 
                            f[i][j] = 0;
    
        go(i, 1, n, 1)
            go(j, 1, m, 1){
                while (sum1[i][j] - sum1[i - ooo][j] - sum1[i][j - ooo] + sum1[i - ooo][j - ooo] != f[i][j])
                    f[i][j]--;
                        maxx = max(maxx, f[i][j]);}
    
        //cout << maxx << "
    ";
    
        go(i, 1, n, 1)
            fo(j, m, 1, 1)
                sum2[i][j] = sum2[i - 1][j] + sum2[i][j + 1] - sum2[i - 1][j + 1] + a[i][j];
        go(i, 1, n, 1)
            fo(j, m, 1, 1) 
                if (a[i][j])
                    g[i][j] = g[i - 1][j + 1] + 1;
                        else 
                            g[i][j] = 0;
    
        go(i, 1, n, 1)
            fo(j, m, 1, 1) {
                while (sum2[i][j] - sum2[i - ppp][j] - sum2[i][j + ppp] + sum2[i - ppp][j + ppp] != g[i][j])
                    g[i][j]--;
                        maxx = max(maxx, g[i][j]);}
    
        //debug();
        cout << maxx;
    #ifdef LOCAL
        Debug("
    My Time: %.3lfms
    ", (double)clock() / CLOCKS_PER_SEC);
    #endif
        return 0;
    }
    
    

    倾斜美感

    第十五次发题解,希望帮助正在debug的同学们寻找错误

  • 相关阅读:
    windows编程:第一个windows程序
    百度地图API多个点聚合时,标注添加的标签label地图刷新就丢失的问题解决
    在WPF的WebBrowser控件中屏蔽脚本错误的提示
    使用SQL语句逐条更新每条记录
    通过 HDU 2048 来初步理解动态规划
    一个乱码问题
    2、设置配置文件
    1、搭建 maven 环境
    MyBatis 缓存机制
    关于 Mybatis 设置懒加载无效的问题
  • 原文地址:https://www.cnblogs.com/yizimi/p/10056274.html
Copyright © 2011-2022 走看看