Codeforces Round #513 (rated, Div. 1 + Div. 2)C. Maximum Subrectangle(数学 + 暴力)

134 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路。

题目 image.png 中文大意

给我们两个数组a和b长度分别为n和m对于每一个ci,j=aibjc_{i,j} = a_i*b_j现在让我们找到一个矩形区间让矩形区间的值<=kk并且矩形区间的面积最大i=x1x2j=y1y2ci,jx\sum_{i=x_1}^{x_2}\sum_{j=y_1}^{y_2}c_{i,j}\leq x

解法

我们先对公式进行拆解因为ci,j=aibjc_{i,j} = a_i*b_j所以i=x1x2j=y1y2aibjx\sum_{i=x_1}^{x_2}\sum_{j=y_1}^{y_2} a_i*b_j\leq x
然后我们把aibja_i和b_j移到求和的式子中去所以现在的式子就变成了 aisumi=x1x2 bjsumj=y1y2x\ a_isum_{i=x_1}^{x_2}\ b_jsum_{j=y_1}^{y_2} \leq x
所以我们现在发现我们现在把题目化成了一段连续的a数组乘一段连续的b数字即可又因为是连续求和所以我们可以使用前缀和去让我们快速知道这段区间的值又因为这题是要求我们再满足条件的同时让面积最大那我们可以预处理下如果是长度为nn的区间最小值是多少这个可以让我们再枚举长度nmn和m时 val(n)val(m)val(n)*val(m)一定是最小的。
我们发现题目的数据范围只有2000那我们就可以直接n2n^2枚举即可

int a[N],b[N];
int lena[N],lenb[N];
void solve()
{
   int n,m; cin >> n >> m;
   rep(i,n) cin >> a[i],lena[i] = 1e18;
   rep(i,m) cin >> b[i],lenb[i] = 1e18;
   rep(i,n) a[i] += a[i-1];
   rep(i,m) b[i] += b[i-1];
   for(int i = 1;i <= n;i++)
      for(int j = i;j <= n;j++)
         lena[i] = min(lena[i],a[j] - a[j - i]);
   for(int i = 1;i <= m;i++)
      for(int j = i;j <= m;j++)
         lenb[i] = min(lenb[i],b[j] - b[j - i]);
   int k; cin >> k;
   int res = 0;
   for(int i = 1; i <= n; i++)
   for(int j = 1; j <= m; j++)
   if(lena[i] * lenb[j] <= k) res = max(res,i*j);
   cout << res << endl;
}