1. 程式人生 > 其它 >Maximum Subrectangle CodeForces - 1060C(字首和+貪心)

Maximum Subrectangle CodeForces - 1060C(字首和+貪心)

技術標籤:字首和貪心

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

Let c be an n×m matrix, where ci,j=ai⋅bj.

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 1≤x1≤x2≤n, 1≤y1≤y2≤m, (x2−x1+1)×(y2−y1+1)=s, and
∑i=x1x2∑j=y1y2ci,j≤x.
Input
The first line contains two integers n and m (1≤n,m≤2000).

The second line contains n integers a1,a2,…,an (1≤ai≤2000).

The third line contains m integers b1,b2,…,bm (1≤bi≤2000).

The fourth line contains a single integer x (1≤x≤2⋅109).

Output
If it is possible to choose four integers x1,x2,y1,y2 such that 1≤x1≤x2≤n, 1≤y1≤y2≤m, and ∑x2i=x1∑y2j=y1ci,j≤x, output the largest value of (x2−x1+1)×(y2−y1+1) among all such quadruplets, otherwise output 0.

Examples
Input
3 3
1 2 3
1 2 3
9
Output
4
Input
5 1
5 4 2 4 5
2
5
Output
1
Note
Matrix from the first sample and the chosen subrectangle (of blue color):
在這裡插入圖片描述
Matrix from the second sample and the chosen subrectangle (of blue color):
在這裡插入圖片描述
思路:雖然是C題,感覺還挺不錯的。
我們可以把上面的那個算式變一下形式,
在這裡插入圖片描述
這樣的話,我們將兩個陣列的字首和求出來,然後分別計算在長度為i的時候,兩個陣列的和的最小值。然後再求一下符合條件的最大的矩陣面積就可以了。
程式碼如下:

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;

const int maxx=2e3+100;
int a[maxx];
int b[maxx];
int sumA[maxx],sumB[maxx],minA[maxx],minB[maxx];
int n,m;
ll x;

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=m;i++) scanf("%d",&b[i]);
	scanf("%lld",&x);
	sumA[0]=sumB[0]=0;
	for(int i=1;i<=n;i++) sumA[i]=sumA[i-1]+a[i];
	for(int i=1;i<=m;i++) sumB[i]=sumB[i-1]+b[i];
	memset(minA,inf,sizeof(minA));
	memset(minB,inf,sizeof(minB));
	for(int i=1;i<=n;i++)
	{
		for(int j=1;i+j<=n+1;j++) minA[i]=min(minA[i],sumA[i+j-1]-sumA[j-1]);
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=1;i+j<=m+1;j++) minB[i]=min(minB[i],sumB[i+j-1]-sumB[j-1]);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++) if((ll)minA[i]*(ll)minB[j]<=x) ans=max(ans,i*j);
	}
	cout<<ans<<endl;
	return 0;
}

努力加油a啊