CF C. Maximum Subrectangle【贪心 + dp】

8 篇文章 0 订阅
3 篇文章 0 订阅

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;
} 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值