zoukankan      html  css  js  c++  java
  • CF1060C Maximum Subrectangle【乘法分配律】【最大子矩阵】

    CF1060C Maximum Subrectangle

    题意翻译

    现在给出一个长度为N的a数列,一个长度为Mb数列. 现在需要构造出一个矩阵c,其中ci,j=ai×bj.再给出一个x,请在矩阵中找出一个最大的矩形,使得这个矩形中的所有值的和小于等于x.

    题目描述

    You are given two arrays aa and bb of positive integers, with length n and m respectively.

    Let c be an n×m matrix, where ci,j=aibj .

    You need to find a subrectangle of the matrix c such that the sum of its elements is at most x , and its area (the total number of elements) is the largest possible.

    Formally, you need to find the largest number s such that it is possible to choose integers x1,x2,y1,y2 subject to n1x1x2n , m1y1y2m , (x2x1+1)×(y2y1+1)=s , and $sum_{i=x_1}^{x2}{sum_{j=y_1}^{y2}{c{i,j}}} leq x.$ 

    输入输出格式

    输入格式:

     

    The first line contains two integers n and m ( 1n,m2000 ).

    The second line contains n integers a1,a2,,an ( 1ai2000 ).

    The third line contains m integers b1,b2,,bm ( 1bi2000 ).

    The fourth line contains a single integer x ( 1x2109 ).

     

    输出格式:

     

    If it is possible to choose four integersx1,x2,y1,y2 such that n1x1x2n ,  m1y1y2m , and xi=x1x2j=y1y2ci,jx , output the largest value of (x2x1+1)×(y2y1+1) among all such quadruplets, otherwise output 0 .

    输入输出样例

    输入样例#1: 复制
    3 3
    1 2 3
    1 2 3
    9
    
    输出样例#1: 复制
    4
    
    输入样例#2: 复制
    5 1
    5 4 2 4 5
    2
    5
    
    输出样例#2: 复制
    1
    

    说明

    Matrix from the first sample and the chosen subrectangle (of blue color):

    Matrix from the second sample and the chosen subrectangle (of blue color):


    Solution

    没想到是道水题QAQ

    可以发现,一个子矩阵的值实际上就是这个子矩阵包括的$a$和$b$数组的乘积,根据乘法分配律可得。

    所以可以预处理出长度一定时最小的$a、b$区间,然后双指针扫描即可。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define LL long long
    using namespace std;
    
    int n, m;
    LL a[2005], b[2005], x;
    LL suma[2005], sumb[2005], ans, maa[2005], mab[2005];
    
    int main() {
        memset(maa, 0x3f3f3f3f, sizeof(maa));
        memset(mab, 0x3f3f3f3f, sizeof(mab));
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i ++) {
            scanf("%lld", &a[i]);
            suma[i] = suma[i - 1] + a[i];
            for(int j = 1; j <= i; j ++)
                maa[j] = min(maa[j], suma[i] - suma[i - j]);
        }
        for(int i = 1; i <= m; i ++) {
            scanf("%lld", &b[i]);
            sumb[i] = sumb[i - 1] + b[i];
            for(int j = 1; j <= i; j ++)
                mab[j] = min(mab[j], sumb[i] - sumb[i - j]);
        }
        scanf("%lld", &x);
        LL j = 0;
        for(LL i = m; i >= 1; i --) {
            while(j < n && maa[j + 1] * mab[i] <= x)
                j ++;
            ans = max(ans, j * i);
        }
        printf("%lld", ans);
        return 0;
    }
  • 相关阅读:
    【JZOJ4244】yi【贪心】
    【JZOJ4244】yi【贪心】
    基本赋值运算符
    自增自减运算符
    字符串的+操作
    算术运算符
    数据类型转换
    键盘输入使用
    基本数据类型长度
    变量
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9817372.html
Copyright © 2011-2022 走看看