解题思路
70分:
很明显的一个线性DP
#include<bits/stdc++.h>
using namespace std;
int n,a[100010],f[100010][3],ans;
int main(){
// freopen("flower.in","r",stdin);
//freopen("flower.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
f[i][1]=f[i][2]=1;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(a[i]<a[j])
f[i][2]=max(f[i][2],f[j][1]+1);
if(a[i]>a[j])
f[i][1]=max(f[i][1],f[j][2]+1);
ans=max(ans,max(f[i][2],f[i][1]));
}
}
printf("%d",ans);
}
100分:
注意到第二个for是找最大值,考虑用树状数组优化。
f[i][1]表示以a[i]结尾,a[i]为最大值时,最大株数
f[i][2]表示以a[i]结尾,a[i]为最小值时,最大株数
tree[a[i]][1]表示前一个比当前高的花高度为a[i]时,已有的大株数
tree[a[i]][2]表示前一个比当前矮的花高度为a[i]时,已有的最大株数
则
int find2(int x){
int ans=0;
for(int i=x;i>0;i-=i&(-i))
{
ans=max(tree[i][2],ans);
}
return ans;
}
int find1(int x){
int ans=0;
for(int i=x;i<=maxn;i+=i&(-i))
{
ans=max(tree[i][1],ans);
}
return ans;
}
f[i][2]=max(f[i][2],find1(a[i]+1)+1);
f[i][1]=max(f[i][1],find2(a[i]-1)+1);
得到f[i][1,]f[i][2]后跟新tree[a[i]][1],tree[a[i]][2]
for(int i=x;i>0;i-=i&(-i))//注意这里不是x~maxn因为f[i][2]更新时要从a[i]+1~maxn中找tree[x][1]最大的,所以后面的更高要被前面矮的更新
tree[i][1]=max(tree[i][1],v);
for(int i=x;i<=maxn;i+=i&(-i))
tree[i][2]=max(tree[i][2],v);
代码
#include<bits/stdc++.h>
using namespace std;
int n,anss,maxn,a[100010],f[100010][3];
int tree[1000010][3];
void add1(int x,int v){
for(int i=x;i>0;i-=i&(-i))
tree[i][1]=max(tree[i][1],v);
}
void add2(int x,int v){
for(int i=x;i<=maxn;i+=i&(-i))
tree[i][2]=max(tree[i][2],v);
}
int find2(int x){
int ans=0;
for(int i=x;i>0;i-=i&(-i))
{
ans=max(tree[i][2],ans);
}
return ans;
}
int find1(int x){
int ans=0;
for(int i=x;i<=maxn;i+=i&(-i))
{
ans=max(tree[i][1],ans);
}
return ans;
}
int main(){
freopen("flower.in","r",stdin);
freopen("flower.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]=a[i]+1;
maxn=max(maxn,a[i]);
f[i][1]=f[i][2]=1;
}
for(int i=1;i<=n;i++)
{
f[i][2]=max(f[i][2],find1(a[i]+1)+1);
f[i][1]=max(f[i][1],find2(a[i]-1)+1);
add2(a[i],f[i][2]);
add1(a[i],f[i][1]);
anss=max(anss,max(f[i][2],f[i][1]));
}
printf("%d",anss);
}
/*
11
1 2 3 4 4 3 2 5 5 6 5
*/