WYT有一把巨大的刷子,刷子的寬度爲M米,如今WYT要使用這把大刷子去粉刷有N列的柵欄(每列寬度都爲1米;每列的高度單位也爲米,由輸入數據給出)。c++
使用刷子的規則是:算法
1.與地面垂直,從柵欄的底部向上刷
2.每次刷的寬度爲M米(當剩餘柵欄寬度不夠M米的話,刷子也可使用,具體看樣例2)
3.對於連續的M列柵欄,刷子從底向上,刷到的高度只能到這M列柵欄的最低高度。數組
WYT請你回答兩個問題:spa
1.最少有多少個單位面積不能刷到(單位面積爲1平米)
2.在知足第一問的條件下,最少刷幾回?code
共兩行:隊列
第一行兩個整數N和M。get
第二行共N個整數,表示N列柵欄的高度it
一行,兩個整數,分別爲最少剩餘的單位面積數量和最少刷的次數。class
5 3 5 3 4 4 5
3 2
int tail = -1;//求向右延伸的寬度 for(int i = 1;i <= n+1;++i){//枚舉到n+1可使前n個都出列 while(tail >= 0 && a[i] < a[que[tail]]){//維護一個單調不上升的隊列 若是第i個的高度比前一個矮了就出隊 r[que[tail]] = i - que[tail];//r是當前節點所能向右延伸的距離 --tail; } que[++tail] = i;//把當前位置入隊 } tail = -1;//求向左延伸的寬度 for(int i = n;i >= 0;--i){ while(tail >= 0 && a[i] < a[que[tail]]){ l[que[tail]] = que[tail] - i; --tail; } que[++tail] = i; } for(int i = 1;i <= n;++i){ if(l[i] + r[i] - 1 >= m)flag[i] = true;//flag標記能刷完 }
for(int i = 1;i <= n;++i){ if(flag[i])mh[i] = a[i]; else mh[i] = mh[i-1]; } for(int i = n;i > 0;--i){ if(!flag[i])mh[i] = max(mh[i],mh[i+1]); sum -= mh[i]; }
int k = 2,ans = 0;//k=2是由於第一個方塊不管如何都要花費一次去刷 while(k <= n){//當前刷到第k個方塊了 int cnt = 1;//第一個方塊已經花費一次去刷了 while(k < n && mh[k] == mh[k+1]){//若是當前的能刷的最高高度和下一個能刷的最高高度同樣 就一塊兒刷掉 cnt++;k++; } ans += cnt/m; if(cnt % m)++ans;//保證向上取整 ++k;//進入下個矩形 }
#include<bits/stdc++.h> using namespace std; const int maxn = 1e7+10; typedef long long ll; ll a[maxn],sum,r[maxn],l[maxn],mh[maxn],que[maxn],flag[maxn]; int main(){ int n,m;scanf("%d%d",&n,&m); for(int i = 1;i <= n;++i){scanf("%lld",&a[i]);sum += a[i];} int tail = -1; for(int i = 1;i <= n+1;++i){ while(tail >= 0 && a[i] < a[que[tail]]){ r[que[tail]] = i - que[tail]; --tail; } que[++tail] = i; } tail = -1; for(int i = n;i >= 0;--i){ while(tail >= 0 && a[i] < a[que[tail]]){ l[que[tail]] = que[tail] - i; --tail; } que[++tail] = i; } for(int i = 1;i <= n;++i){ if(l[i] + r[i] - 1 >= m)flag[i] = true; } for(int i = 1;i <= n;++i){ if(flag[i])mh[i] = a[i]; else mh[i] = mh[i-1]; } for(int i = n;i > 0;--i){ if(!flag[i])mh[i] = max(mh[i],mh[i+1]); sum -= mh[i]; } int k = 2,ans = 0; while(k <= n){ int cnt = 1; while(k <= n+1 && mh[k] == mh[k-1]){ cnt++;k++; } ans += cnt/m; if(cnt % m)++ans; ++k; } printf("%lld\n%d",sum,ans); return 0; }