SOJ 3085: windy‘s cake V http://acm.scu.edu.cn/soj/problem.action?id=3085
Problem: Given a list of $n$ positive integers $num[1], ..., num[n]$, denote the score of one sublist from $i$ to $j$ as $(\min_{i\le k\le j}num[k])*\left(\Sigma_{k=i}^{j}num[k]\right)$. The question is that which sublist has the largest score? Output the largest score.
Analysis: we can enumerate each $num[i], 1\le i\le n$ to be the minimum number in one sublist. Therefore, for each $num[i], 1\le i\le n$, we need to find the corresponding sublist, that is, to find the first number $num[i‘]$ that is smaller than $num[i]$ from $i-1$ to $1$ and the first number $num[i‘‘]$ that is smaller than $num[i]$ from $i+1$ to $n$ (similar to SOJ 2511, please see here). Then, for $num[i]$ the score $score[i]=num[i]*\left(\Sigma_{k=i‘}^{i‘‘}num[k]\right)$, and the solution is $\max_{1\le k\le n}score[i]$.
Technique: Maintaining an increasing stack.
Code:
#include<iostream> #include<stack> using namespace std; struct node { int no; int num; int prevNo; node(){prevNo=0;} }; node arr[100005]; stack<node>s; long long sum[100005]; int main() { int n; int temp1; int i; long long temp2; long long ans; while(scanf("%d",&n)==1) { sum[0]=0; for(i=1;i<=n;i++) { scanf("%d",&temp1); sum[i]=sum[i-1]+temp1; arr[i].no=i; arr[i].num=temp1; } arr[0].no=0; arr[0].num=-1; arr[n+1].no=n+1; arr[n+1].num=-1; s.push(arr[0]); ans=0; for(i=1;i<=n+1;i++) { while(arr[i].num<s.top().num) { temp2=s.top().num*(sum[i-1]-sum[s.top().prevNo]); ans=temp2>ans ? temp2 : ans; s.pop(); } arr[i].prevNo=s.top().no; s.push(arr[i]); } while(!s.empty()) s.pop(); printf("%lld\n",ans); } return 0; }
原文地址:https://www.cnblogs.com/ClearMoonlight/p/10529584.html