• Codeforces 1060C Maximum Subrectangle(子矩阵+预处理)


    题意:给出数组a,b,组成矩阵c,其中$c_{ij}=a_i*b_j$,找出最的大子矩阵,使得矩阵元素和<=x,求这个矩阵的size

    n,m<=2000

    思路:对于子矩阵(l1...r1)*(l2...r2),矩阵元素和为(a[l1]+a[l1+1]+...+a[r1])*(b[l2]+b[l2+1]+...+b[r2])

    这样处理出长度为i的连续数组最小和aa[i],bb[i],再枚举一下长度即可

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    //#include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 100003;
    const int maxn = 2e5+100;
    const int maxm = 2e5+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    ll a[maxn],b[maxn];
    ll aa[maxn], bb[maxn];
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
        mem(a, 0);
        mem(b, 0);
        for(int i = 1; i <= n; i++){
            scanf("%lld", &a[i]);
            a[i]+=a[i-1];
        }
        for(int i = 1; i <= m; i++){
            scanf("%lld", &b[i]);
            b[i]+=b[i-1];
        }
        ll ans = 0;
        ll tmp = 0;
        ll x;
        scanf("%lld", &x);
        mem(aa,0x3f);
        mem(bb,0x3f);
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= i; j++){
                //j~i
                aa[i-j+1]=min(aa[i-j+1],a[i]-a[j-1]);
            }
        }
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= i; j++){
                bb[i-j+1]=min(bb[i-j+1],b[i]-b[j-1]);
            }
        }
    
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(aa[i]*bb[j]<=x)ans = max(ans, 1ll*i*j);
            }
        }
        printf("%lld", ans);
        return 0;
    }
  • 相关阅读:
    【JAVA
    【Android
    【开发工具
    【开发工具
    【开发工具
    【Android
    【Android
    【JavaEE】之MyBatis查询缓存
    【JavaEE】之MyBatis逆向工程的使用
    新的起点 Entry KINGSOFT
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/9780894.html
Copyright © 2020-2023  润新知