Terrible Sets

来源:互联网 发布:解手机密码软件 编辑:程序博客网 时间:2024/06/05 19:48

Terrible Sets

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 60000/30000K (Java/Other)
Total Submission(s) : 26   Accepted Submission(s) : 14
Problem Description
Let N be the set of all natural numbers {0 , 1 , 2 , . . . }, and R be the set of all real numbers. wi, hi for i = 1 . . . n are some elements in N, and w0 = 0. 
Define set B = {< x, y > | x, y ∈ R and there exists an index i > 0 such that 0 <= y <= hi ,∑0<=j<=i-1wj <= x <= ∑0<=j<=iwj} 
Again, define set S = {A| A = WH for some W , H ∈ R+ and there exists x0, y0 in N such that the set T = { < x , y > | x, y ∈ R and x0 <= x <= x0 +W and y0 <= y <= y0 + H} is contained in set B}. 
Your mission now. What is Max(S)? 
Wow, it looks like a terrible problem. Problems that appear to be terrible are sometimes actually easy. 
But for this one, believe me, it's difficult.
 

Input
The input consists of several test cases. For each case, n is given in a single line, and then followed by n lines, each containing wi and hi separated by a single space. The last line of the input is an single integer -1, indicating the end of input. You may assume that 1 <= n <= 50000 and w<sub>1</sub>h<sub>1</sub>+w<sub>2</sub>h<sub>2</sub>+...+w<sub>n</sub>h<sub>n</sub> < 10<sup>9</sup>.
 

Output
Simply output Max(S) in a single line for each case.
 

Sample Input
31 23 41 233 41 23 4-1
 

Sample Output
1214
 
      题意很不好懂的,懂了之后会挺简单。形象的理解,给n个底边长为w,高为h的矩形排成一排,求能分割出来的最大矩形。先看一下这个题,算是个简单版吧,重点是单调栈,大致一样的方法,不再多说。点击打开链接

代码如下:

#include<iostream>#include<stdio.h>using namespace std;long long int h[100010];long long int w[100010];long long int sum[100010];int l[100010];int r[100010];int s[100010];int main(){int N;int top;while(cin>>N && N>0){    sum[0]=0;        for(int i=1;i<=N;i++){scanf("%I64d",&w[i]);scanf("%I64d",&h[i]);sum[i]=sum[i-1]+w[i];l[i]=i;r[i]=i;}top=0;for(int i=1;i<=N;i++)   //向左找{while(top && h[i]<=h[s[top]])//递增栈                top--;            if(top==0)                l[i]=1;            else                l[i]=s[top]+1;//s[top]存的数的值肯定是比a[i]小的,所以地s[top]+1个位置即为所求            s[++top]=i;}top=0;for(int i=N;i>=1;i--){while(top && h[i]<=h[s[top]])                top--;            if(top==0)                r[i]=N;            else                r[i]=s[top]-1;            s[++top]=i;}long long int maxn=0;long long int area;for(int i=1;i<=N;i++){area=h[i]*(sum[r[i]]-sum[l[i]-1]);if(maxn<area)maxn=area;}printf("%I64d\n",maxn);}return 0;}




原创粉丝点击