北京清北 綜合強化班 Day4 T1
阿新 • • 發佈:2017-10-05
cstring pre limit 描述 onclick name 兩個 pla urn
財富(treasure)
Time Limit:1000ms Memory Limit:128MB
題目描述
LYK有n個小夥伴。每個小夥伴有一個身高hi。
這個遊戲是這樣的,LYK生活的環境是以身高為美的環境,因此在這裏的每個人都羨慕比自己身高高的人,而每個人都有一個屬性ai表示它對身高的羨慕值。
這n個小夥伴站成一列,我們用hi來表示它的身高,用ai來表示它的財富。
每個人向它的兩邊望去,在左邊找到一個最近的比自己高的人,然後將ai朵玫瑰給那個人,在右邊也找到一個最近的比自己高的人,再將ai朵玫瑰給那個人。當然如果沒有比自己身高高的人就不需要贈送別人玫瑰了。也就是說一個人會給0,1,2個人玫瑰(這取決於兩邊是否有比自己高的人)。
每個人都會得到若幹朵玫瑰(可能是0朵),LYK想知道得了最多的玫瑰的那個人得了多少玫瑰。(然後嫁給他>3<)
輸入格式(treasure.in)
第一行一個數n表示有n個人。
接下來n行,每行兩個數hi,ai。
輸出格式(treasure.out)
一個數表示答案。
輸入樣例
3
4 7
3 5
6 10
輸出樣例
12
樣例解釋
第一個人會收到5朵玫瑰,第二個沒人送他玫瑰,第三個人會收到12朵玫瑰。
數據範圍
對於50%的數據n<=1000,hi<=1000000000。
對於另外20%的數據n<=50000,hi<=10。
對於100%的數據1<=n<=50000,1<=hi<=1000000000。1<=ai<=10000。
思路:
1.首先這題暴力可過。。。
2.std:每個點向左找一個最近的且比它大的,向右找最近且比向右找最近且比它大的它大的從右往左枚舉過來
for (int i=n; i>=1; i--) { while (r && s[r]<=h[i]) r--; b[q[r]]+=a[i]; s[++r]=h[i]; q[r]=i; } //b[i]第i個人收到的玫瑰數 //q[i]在單調的數列中第i個位置是n個人中的哪個人
求最靠近它且比它高的那個位置是哪個
3.My
正著跑一邊單調隊列(單調下降),然後倒著跑一遍,每次更新就判斷一下隊尾元素是否後面的人被更新,如果沒有:先讓想加入的這個點i的ans加上隊尾元素的a值,然後標記
最後把ans數組sort一遍,輸出ans[n]即可
上代碼:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define LL long long using namespace std; const int M = 50055; int n,qt,a[M]; LL h[M],q1[M],q2[M],ans[M]; bool visq[M]; int main() { freopen("treasure.in","r",stdin); freopen("treasure.out","w",stdout); scanf("%d",&n); for(int i=1; i<=n; ++i) { scanf("%d%d",&h[i],&a[i]); while(qt>0 && h[i]>q1[qt]) { //right if(!visq[q2[qt]]) { ans[i]+=a[q2[qt]]; visq[q2[qt]]=true; } qt--; } q1[++qt]=h[i]; q2[qt]=i; } qt=0; memset(visq,0,sizeof(visq)); memset(q1,0,sizeof(q1)); memset(q2,0,sizeof(q2)); for(int i=n; i>=1; --i) { //left while(qt>0 && h[i]>q1[qt]) { //right if(!visq[q2[qt]]) { ans[i]+=a[q2[qt]]; visq[q2[qt]]=true; } qt--; } q1[++qt]=h[i]; q2[qt]=i; } sort(ans+1,ans+n+1); printf("%d",ans[n]); return 0; }My
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; int n,s[50002],d[50002],ans[50002],ANS,a[50002],b[50002],r,i; int main() { freopen("treasure.in","r",stdin); freopen("treasure.out","w",stdout); cin>>n; for (i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]); s[1]=a[1]; d[1]=1; r=1; for (i=2; i<=n; i++) { while (r!=0 && a[i]>s[r]) { ans[i]+=b[d[r]]; r--; } r++; s[r]=a[i]; d[r]=i; } s[1]=a[n]; d[1]=n; r=1; for (i=n-1; i>=1; i--) { while (r!=0 && a[i]>s[r]) { ans[i]+=b[d[r]]; r--; } r++; s[r]=a[i]; d[r]=i; } for (i=1; i<=n; i++) ANS=max(ANS,ans[i]); cout<<ANS; return 0; }std
北京清北 綜合強化班 Day4 T1