zoukankan      html  css  js  c++  java
  • CF1060C Maximum Subrectangle

    现在给出一个长度为$N$的$a$数列,一个长度为$M$的$b$数列. 现在需要构造出一个矩阵$c$,其中$c_{i,j}=a_i imes b_j$.再给出一个$x$,请在矩阵中找出一个最大的矩形,使得这个矩形中的所有值的和小于等于$x$.

    题解

    刚开始打算上矩形里搞,然而突然想到如果是那样的话直接给出矩形就好了干嘛要有数列……

    然后发现$sum_{i=x1}^{x2}sum_{j=y1}^{y2}c_{i,j}=sum_{i=x1}^{x2}sum_{j=y1}^{y2}a_i*b_j=sum_{i=x1}^x2a_i*sum_{j=y1}^{y2}b_j$

    于是就变成两个数列选出两个区间的问题了……

    然后因为数列很小,我们可以先枚举数列$b$,设$res[i]$表示$b$数列中长度为$i$的区间的最小值是多少,直接暴力预处理

    然后枚举$a$的区间,因为对于同一个左端点来说,右端点右移的时候能匹配上的$b$的长度肯定是不升的,于是用指针记录一下就行了

    复杂度$O(n^2)$

     1 //minamoto
     2 #include<bits/stdc++.h>
     3 #define ll long long
     4 #define inf 0x3f3f3f3f
     5 using namespace std;
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
     9 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    10 inline int read(){
    11     #define num ch-'0'
    12     char ch;bool flag=0;int res;
    13     while(!isdigit(ch=getc()))
    14     (ch=='-')&&(flag=true);
    15     for(res=num;isdigit(ch=getc());res=res*10+num);
    16     (flag)&&(res=-res);
    17     #undef num
    18     return res;
    19 }
    20 const int N=2005;
    21 int a[N],b[N],suma[N],sumb[N],res[N],n,m,tot,ans=0,mn1=inf,mn2=inf;
    22 void init(){
    23     memset(res,0x3f,sizeof(res));
    24     for(int i=1;i<=m;++i)
    25     for(int j=i;j<=m;++j)
    26     cmin(res[j-i+1],sumb[j]-sumb[i-1]);
    27 }
    28 int main(){
    29 //    freopen("testdata.in","r",stdin);
    30     n=read(),m=read();
    31     for(int i=1;i<=n;++i)
    32     a[i]=read(),suma[i]=suma[i-1]+a[i],cmin(mn1,a[i]);
    33     for(int i=1;i<=m;++i)
    34     b[i]=read(),sumb[i]=sumb[i-1]+b[i],cmin(mn2,b[i]);
    35     tot=read();
    36     if(mn1*mn2>tot) return puts("0"),0;
    37     init();
    38     for(int i=1;i<=n;++i){
    39         int len=m;
    40         for(int j=i;j<=n;++j){
    41             while(len&&1ll*res[len]*(suma[j]-suma[i-1])>tot) --len;
    42             if(!len) break;
    43             cmax(ans,len*(j-i+1));
    44         }
    45     }
    46     printf("%d
    ",ans);
    47     return 0;
    48 }
  • 相关阅读:
    easyui带file上传控件表达提交
    WebApi返回json
    同一个项目中使用MVC控制器和WebAPI控制器
    jquery disabled
    ITIL(Information Technology Infrastructure Library )
    jquery.formatDateTime
    sqlserver 表连接更新字段
    C#分页的总页数算法
    Angular入门教程三
    Angular入门教程二
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9765807.html
Copyright © 2011-2022 走看看