zoukankan      html  css  js  c++  java
  • 洛谷 P2216 [HAOI2007]理想正方形

    洛谷

    说这是一道单调队列好题,但是我并不是用单调队列做的诶。

    如果往最暴力的方向去想,肯定是(n^3)(dp)了。

    (f[i][j][k])代表当前正方形的左上角定点是((i,j)),边长是(k)的正方形的最佳答案。

    转移方程很简单,但是你一定会妥妥的( exttt{TLE})

    那么我们怎么做呢?

    往倍增的方向去想,设(f[i][j][k])表示左上角为((i,j)),边长为(2^j)的正方形的最佳答案。

    那么状态就这么转移:

    [mx[i][j]=max(mx[i][j],max(mx[i+(1<<k)][j+(1<<k)],max(mx[i+(1<<k)][j],mx[i][j+(1<<k)]))); ]

    [mn[i][j]=min(mn[i][j],min(mn[i+(1<<k)][j+(1<<k)],min(mn[i+(1<<k)][j],mn[i][j+(1<<k)]))); ]

    很简单的转移方程,不过复杂度肯定比不上单调队列的做法了。

    显然复杂度(O(n^2~log(n)))

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=1001;
    int a,b,n,t[N][N];
    int mx[N][N],mn[N][N],ans=2000000000,tmp;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>a>>b>>n;
        for (int i=0;i<a;++i)
            for (int j=0;j<b;++j)
                cin>>t[i][j],mn[i][j]=mx[i][j]=t[i][j];
        while ((1<<(tmp+1))<=n) ++tmp;
        for (int k=0;k<tmp;++k)
            for (int i=0;i+(1<<k)<a;++i)
                for (int j=0;j+(1<<k)<b;++j) {
                    mx[i][j]=max(mx[i][j],max(mx[i+(1<<k)][j+(1<<k)],max(mx[i+(1<<k)][j],mx[i][j+(1<<k)])));
                    mn[i][j]=min(mn[i][j],min(mn[i+(1<<k)][j+(1<<k)],min(mn[i+(1<<k)][j],mn[i][j+(1<<k)])));
                }
        for (int i=0;i<=a-n;++i)
            for (int j=0;j<=b-n;++j) {
                int MX=max(mx[i][j],max(mx[i+n-(1<<tmp)][j+n-(1<<tmp)],max(mx[i+n-(1<<tmp)][j],mx[i][j+n-(1<<tmp)])));
                int MN=min(mn[i][j],min(mn[i+n-(1<<tmp)][j+n-(1<<tmp)],min(mn[i+n-(1<<tmp)][j],mn[i][j+n-(1<<tmp)])));
                ans=min(MX-MN,ans);
            }
        cout<<ans;
        return 0;
    }
    
  • 相关阅读:
    C语言-const和volatile深度分析
    C语言循环语句工程用法
    C分支语句的工程用法
    函数对象分析
    关于protel电路图导入word
    单片机程序编写与下载
    关于Protel输出PDF原理图
    关于定时器、外部中断的一些理解
    锁存、译码介绍
    关于Proteus电压设置
  • 原文地址:https://www.cnblogs.com/fushao2yyj/p/9609255.html
Copyright © 2011-2022 走看看