hdu1506 dp:长度不等的山峰找最大面积矩形(或者用单调栈)
先用单调上升栈处理左右端点A了,稳稳地O(n)做法
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<stack> 5 using namespace std; 6 stack<int>s,s1; 7 int l[100005],r[100005],a[100005]; 8 int main() 9 { 10 int i,n,y; 11 while (~scanf("%d",&n)&&n) 12 { 13 while (!s.empty()) {s.pop(); s1.pop();} 14 for (i=1;i<=n;i++) 15 { 16 scanf("%d",&a[i]); 17 while (!s.empty()) 18 { 19 y=s.top(); 20 if (y<a[i]) break; 21 else {s.pop(); s1.pop();} 22 } 23 if (s.empty()) l[i]=1; 24 else l[i]=s1.top()+1; 25 s.push(a[i]); s1.push(i); 26 } 27 while (!s.empty()) {s.pop(); s1.pop();} 28 for (i=n;i>=1;i--) 29 { 30 while (!s.empty()) 31 { 32 y=s.top(); 33 if (y<a[i]) break; 34 else {s.pop(); s1.pop();} 35 } 36 if (s.empty()) r[i]=n; 37 else r[i]=s1.top()-1; 38 s.push(a[i]); s1.push(i); 39 } 40 long long x=0; 41 for (i=1;i<=n;i++) 42 if ((long long)a[i]*(long long)(r[i]-l[i]+1)>x) x=(long long)a[i]*(long long)(r[i]-l[i]+1); 43 printf("%I64d\n",x); 44 } 45 return 0; 46 }
妈蛋竟然没有dp找左右端点快,暗想一定是数据有点弱
1 #include<stdio.h> 2 #include<string.h> 3 int a[100005],l[100005],r[100005]; 4 int main() 5 { 6 int i,n,y; 7 while (~scanf("%d",&n)&&n) 8 { 9 for (i=1;i<=n;i++) scanf("%d",&a[i]); 10 l[1]=1; 11 for (i=2;i<=n;i++) 12 { 13 y=i; 14 while (y>1&&a[i]<=a[y-1]) y=l[y-1]; 15 l[i]=y; 16 } 17 r[n]=n; 18 for (i=n-1;i>=1;i--) 19 { 20 y=i; 21 while (y<n&&a[i]<=a[y+1]) y=r[y+1]; 22 r[i]=y; 23 } 24 long long x=0; 25 for (i=1;i<=n;i++) 26 if ((long long)a[i]*(long long)(r[i]-l[i]+1)>x) x=(long long)a[i]*(long long)(r[i]-l[i]+1); 27 printf("%I64d\n",x); 28 } 29 }
注意dp的状态转移,是比较当前最左的左边一个和自己的大小