Psychos in a Line CodeForces - 320D
算法:单调栈,模拟
注释:
- 单调栈是寻找当前数字某一方向(左边或右边)第一个比起大(或者小)的数字。
- 利用单调栈找到当前数左边第一个比其大的数。到达当前数时,保留在栈中的数字一定是非单调递减的数字,即未能被杀死的人;从栈中弹出的人为可以被当前这个人所能杀死的人。因为一个人可以同时杀死他人和被他人杀死,所以一列单调递减的数字,可以看做最前面的人可一次性杀死到单调递减最后一个人。
- 利用ans[a[i]]数组保存第i个人a[i]所能杀死最多的人所需要的步数。
#include<iostream>
#include<cstdio>
#include<stack>
#define N 100010
using namespace std;
int a[N],ans[N];
stack<int>s;
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n,i;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=n;i>=1;i--)
{
if(s.empty())
{
ans[a[i]]=0;
s.push(a[i]);
continue;
}
if(a[i]<s.top())
{
s.push(a[i]);
ans[a[i]]=0;
}
else if(a[i]>s.top())
{
int temp=max(1,ans[s.top()]);
s.pop();
while(!s.empty()&&a[i]>s.top())
{
temp=max(temp+1,ans[s.top()]);//其实就是找它前面的人杀人所需最多的步数 ,但是至少也得每次加1
s.pop();
}
ans[a[i]]=temp;
s.push(a[i]);
}
}
int maxx=0;
for(i=1;i<=n;i++)
maxx=max(maxx,ans[i]);
cout<<maxx;
return 0;
}
Report Codeforces - 631C
算法:单调栈,模拟
注释:
- 单调栈的另一个作用就是再将整个数列遍历完成之后,储存一个包含最后一个数字的单调递减(或递增)序列。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#define N 200010
using namespace std;
struct manager{
int r,t;
}b[N];
int a[N],top,temp[N],f,h;
manager s[N];
int main()
{
int n,m,i,j;
manager res;
cin>>n>>m;
for(i=1;i<=n;i++)
{
cin>>a[i];
temp[i]=a[i];
}
for(i=1;i<=m;i++)
{
cin>>res.t>>res.r;
if(!top)s[++top]=res;
else
{
while(top!=0&&res.r>=s[top].r)
top--;
s[++top]=res;
}
}
f=1;
h=s[1].r;
sort(temp+1,temp+h+1);
for(i=2;i<=top;i++)
{
//cout<<s[i].r<<endl;
for(j=s[i-1].r;j>s[i].r;j--)
{
//cout<<a[j]<<" "<<temp[f]<<endl;
if(s[i-1].t==1)a[j]=temp[h--];
else if(s[i-1].t==2)a[j]=temp[f++];
}
}
for(i=1;i<=s[top].r;i++)
if(s[top].t==1)a[i]=temp[f++];
else if(s[top].t==2)a[i]=temp[h--];
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}