http://codeforces.com/contest/1060/problem/C
给你一个两个数组 分别n , m 长度
然后给你n个数 m个数 一个x
然后这n + m个数 构成一个矩形
比如
3 3
1 2 3
1 2 3
表:就是for(i=n个数) for (j=m个数) i*j
1 2 3
2 4 6
3 6 9
再通俗点说 n = 2 m = 2
a b ac ad
c d bc bd 有没有发现跟乘法分配律很像
然后想到前缀和 a (a + b)
c (c + d)
然后可以发现 前缀和之乘 就是块的和
题目要求输出的是 那些块(里面数的和 小于等于x)然后输出最大块的面积
可以发现 1面积 2面积 3面积 4面积。。。。每种类型都好多 比如3*3的 1面积就有9个 4面积就有4个
一开始打算 把所有的都扫一边 看了一下会超时
然后我就想 那个结论,我只要拿一个数组保存 每一段长度为1 为2 为3 。。。的区间和 最小的值
最后直接扫n(有1长度 2长度。。n长度 n个) * m(同理)个矩形不就好了
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn = 2100;
int a[maxn], b[maxn], Mina[maxn], Minb[maxn];
int main(){
int n, m;
a[0] = b[0] = 0;
while (~scanf("%d%d", &n, &m)){
//前缀和
for (int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
a[i] += a[i - 1];
}
for (int i = 1; i <= m; ++i) {
scanf("%d", &b[i]);
b[i] += b[i - 1];
}
int x;
scanf("%d", &x);
memset(Mina, inf, sizeof(Mina));
memset(Minb, inf, sizeof(Minb));
//printf("%d", Mina[1]);
//Mina Minb 下标 是长度
for (int i = 1; i <= n; ++i){
for (int j = 0; j < i; ++j){
Mina[i - j] = min(Mina[i - j], a[i] - a[j]);
}
}
for (int i = 1; i <= m; ++i){
for (int j = 0; j < i; ++j){
Minb[i - j] = min(Minb[i - j], b[i] - b[j]);
}
}
int ans = 0;
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j){
//会爆
//if (Mina[i] * Minb[j] <= x){
if (Minb[j] <= x / Mina[i]){
ans = max (ans, i * j);
}
}
}
printf("%d\n", ans);
}
return 0;
}