BJ80中集训--多线程

2333 233

这算是一道比较综合的思路题吧,考场上只想出了后半部分的贪心

考虑如果我们已经求出了一种可行情况,那么其他的答案不过只有三种:

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值