标签:
单调队列
题意是:把一个 长度 为 n 的 数列 分成任意份,使每一份的和不超过m,求每一份的最大值的和,使和最小
动态规划方程 是 f [i] = f[j] + max{ f[j+1] , f[j+2] , f[i] };
朴素的算法是 O(n^2);
用 单调队列 表示一个递减 的 队列 ,则 不需要 求 每块区域的最大值
哎哎哎……不知道怎么说
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <deque> #include <iterator> using namespace std; typedef long long ll; const int MAXN=10e5+10; const int INF=0x7fffffff; ll arr[MAXN]; ll f[MAXN]; int main(){ // freopen("input.txt","r",stdin); int n; ll m; while(~scanf("%d%I64d",&n,&m)){ f[0]=0; deque<int>dq; while(!dq.empty()){ dq.pop_back(); } int k=0; bool flag=0; ll sum=0; for(int i=1;i<=n;i++){ scanf("%I64d",&arr[i]); if(flag){ continue; } if(arr[i]>m){ flag=1; continue; } sum += arr[i]; while(sum > m){ sum -= arr[++k]; } while(!dq.empty() && arr[dq.back()]<=arr[i]){ dq.pop_back(); } dq.push_back(i); while(!dq.empty() && dq.front() <= k){ dq.pop_front(); } int kk=k; f[i] = INF; for(deque<int>::iterator it=dq.begin();it<dq.end();it++){ f[i]=min(f[kk]+arr[*it],f[i]); kk=*it; } } printf("%I64d\n",flag?-1:f[n]); } return 0; }
广告印刷……
题意:一排 宽度为 1 ,长度不同 的 高楼,在上面印 矩形 广告,求矩形的 最大 印刷 面积
木桶的短板原理,最短的会拉低矩形的高度。
对于某点 i ,以点为最低点, 左边能 延续的 最大长度 ,和右边 所能延续的 最大距离 ,则面积 就 求出
左延续需要借助 一个 递增 的单调队列 则 前面的 高度,一定可以代表可以 到达 i 的 矩形,如果 以 i 为 最低点作为矩形的话
则 需要从 单调队列队尾的 下一个 点开始 则宽度 为 i - dq.back() - 1
右延续同上,从右边到左的 递增 的 单调序列 求 宽度 dq.back() - i - 1;
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <deque> using namespace std; //广告印刷,需要求队列里面的最小值,维持递增的单调队列 const int MAXN = 4000000+10; int h[MAXN]; int L[MAXN]; int R[MAXN]; int main(){ freopen("input.txt","r",stdin); int n; deque<int>dq; while(~scanf("%d",&n)){ int ans = 0; while(!dq.empty()){ dq.pop_back(); } dq.push_back(0); h[0]=h[n+1]= -1; for(int i=1;i<=n;i++){ scanf("%d",&h[i]); while(!dq.empty() && h[dq.back()] >= h[i]){ dq.pop_back(); } L[i]=i-dq.back()-1; dq.push_back(i); } while(!dq.empty()){ dq.pop_back(); } dq.push_back(n+1); for(int i=n;i>0;i--){ while(!dq.empty() && h[dq.back()] >= h[i]){ dq.pop_back(); } R[i]=dq.back()-i-1; ans=max(ans,h[i]*(R[i]+L[i]+1)); dq.push_back(i); } printf("%d\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/hanbinggan/p/4782307.html