这算是一道比较综合的思路题吧,考场上只想出了后半部分的贪心
考虑如果我们已经求出了一种可行情况,那么其他的答案不过只有三种:
1.上升序列给一个给下降序列
2.下降序列给一个给上升序列
3.两个序列交换一个元素
因为如果超过一个元素的操作,就会在另一种里面形成不合法的情况
接下来只需要求出一个可行解即可O(n)求答案了
如果两个序列已经相交过了,就已经互不影响了
否则如果新加入的一个值不在两个序列末尾值的中间时,就可以贪心决定,让它们直接相交了
否则考虑下一个元素,如果是上升的,这一个给上升序列更优,反之亦然,亦证
然后就可以做出来了(话说我今天T1 int+int>int 直接爆零了 QwQ)
不太想写就贴一个爆搜吧,也就只有今天老师懒得出数据直接随机才能过了
已知可以卡到至少n^2的复杂度呢
#include<bits/stdc++.h>
using namespace std;
const int N=500010;
const int mod=1e9+7;
int a[N];
int T,n,ans;
int dfs(int cur,int las,bool kind)
{
if(cur==n)return 1;
if(kind==1){
int tmp=0;
if(a[cur+1]>a[cur])tmp=tmp+dfs(cur+1,las,1);
if(a[cur+1]<las)tmp=tmp+dfs(cur+1,a[cur],0);
return tmp;
}
if(kind==0){
int tmp=0;
if(a[cur+1]<a[cur])tmp=tmp+dfs(cur+1,las,0);
if(a[cur+1]>las)tmp=tmp+dfs(cur+1,a[cur],1);
return tmp;
}
}
int dd[N],tot;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
if(n==0){printf("1\n");continue;}
tot=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
dd[++tot]=a[i];
}
sort(dd+1,dd+1+tot);
for(int i=1;i<=n;i++)a[i]=lower_bound(dd+1,dd+1+tot,a[i])-dd;
int ans=dfs(1,0,0)+dfs(1,tot+1,1);ans%=mod;
printf("%d\n",ans);
}
return 0;
}