Link:http://poj.org/problem?id=2082
Terrible Sets
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
1h
1+w
2h
2+...+w
nh
n < 10
9.
Output
Simply output Max(S) in a single line for each case.
Sample Input 3 1 2 3 4 1 2 3 3 4 1 2 3 4 -1 Sample Output 12 14 Source |
题意:直接讲样例给定意思就好了,万恶的出题人,简简单单的意思,把题目绕来绕去,说得如此复杂(ps:可能是自己的读题能力或对集合部分的内容表述不理解才会这样说,出题人不喜勿喷哦)。就是从左到右依次给你一个矩形的宽和高,问在这从左到右的矩形连成的图形中,能够找到的最大矩形面积是多少。
编程思想:类似我之前做过的一道题,这题不同之处只是给出的矩形的宽不是固定为1,其他一样。详细讲解见http://blog.csdn.net/enjoying_science/article/details/47904621
AC code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#define PI acos(-1.0)
#define LINF 1000000000000000000LL
#define eps 1e-8
#define LL long long
#define MAXN 1000010
using namespace std;
const int INF=0x3f3f3f3f;
struct Rec{
LL h;
LL w;
int id;
}r[MAXN];//r[i]表示以第i条柱状图能向左向右扩展的最大矩形
Rec st[MAXN];//单调递增栈
LL ans;
int main()
{
int i,j,n,hi,wi,top;
while(scanf("%d",&n)!=EOF)
{
if(n==-1)
break;
top=0;//栈顶指针(栈的大小)
for(i=1;i<=n;i++)
{
scanf("%d%d",&wi,&hi);
r[i].h=hi;
r[i].w=wi;
r[i].id=i;
j=0;
while(top!=0&&r[i].h<=st[top].h)//要入栈的元素不满足单调栈严格递增,删除栈中元素直到满足,
{ //同时这些出栈的元素能向右扩展的宽度也确定下来了,可以直接更新
r[st[top].id].w+=j;//j表示能向右扩展的宽度
j=r[st[top].id].w;
top--;//出栈
}
r[i].w+=j;//更新当前矩形能向左扩展的宽度(因为是一直向右走,所以每次都能更新向左扩展的宽度)
st[++top]=r[i];//入栈
}
j=0;
while(top!=0)
{
r[st[top].id].w+=j;//j表示能向右扩展的宽度
j=r[st[top].id].w;
top--;//出栈
}
ans=-INF;
for(i=1;i<=n;i++)
{
//printf("%lld %lld %lld\n",r[i].h,r[i].w,r[i].h*r[i].w);
ans=max(ans,r[i].h*r[i].w);
}
printf("%lld\n",ans);
}
return 0;
}