CSP 2021 惨痛

都别多说废话了,人已经麻了。

考前一天晚上睡不着,4:30才睡,一整天人事不省。

坐大巴去绵阳考试,在车上也睡不着,看着沿途的风景,心事重重。

停课一个月以来,文化课动都没有动。月考班上一下就拉开了差距。也不知道该怎么办。

到了考场,中午吃的很好。但是还十分紧张。

考场上,看到T1人已经傻了。一开始想用树状数组,导致思路一开始就是错的。 结果还调傻了。

三个小时才干完。看了一下T2 ,乱写了一个暴力,然后0分了。

码力严重不足,心态+状态导致了此次的失败。

眼前只能冲一下NOIP2021了,文化课没了。

考完联赛看我10天学完两个月内容然后冲冲半期。

哎~~ 下面就放一下代码吧: T1,用两个堆来维护。一个放飞机的起点终点,一个维护着陆飞机的廊桥和起飞时间 然后模拟做 

 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+50;
int n,m1,m2,c1[N],c2[N];
struct aircraft{//每一次航班的开始与结束时间,还有id 
	int s,t,id;
	bool operator < (const aircraft &b)const{return s<b.s;};
}a1[N],a2[N];

struct node{//每一个航班的占用廊桥和结束时间 
	int t,id;
	bool operator < (const node &b) const {return t>b.t;};
};

priority_queue<node>l1,l2;//小根堆 
priority_queue<int,vector<int>,greater<int> >e1,e2;


int main()
{
	//freopen("airport3.in","r",stdin);
	cin>>n>>m1>>m2;
	for(int i=1;i<=m1;i++){
		cin>>a1[i].s>>a1[i].t;
		//a1[i].id=i;
	}	
	for(int i=1;i<=m2;i++){
		cin>>a2[i].s>>a2[i].t;
		//a2[i].id=i;
	}
	sort(a1+1,a1+m1+1);
	sort(a2+1,a2+m2+1);
	
	for(int i=1;i<m1;i++){
		e1.push(i);//所有廊桥都属于空闲状态,每一个都有编号 
	}
	int k=0;
	for(int i=1;i<=m1;i++){//每一个航班 
		while(l1.size()&&a1[i].s>l1.top().t){//在停靠的航班的堆不为空 且 该航班的着陆时间大于等于某航班的起飞时间 
			e1.push(l1.top().id);//该航班所在廊桥空闲 
			l1.pop();//航班离开,廊桥为空 
		}
		k=e1.top(),e1.pop();//先去编号最小的廊桥 
		++c1[k],l1.push(node{a1[i].t,k});//该廊桥容纳的数量加一,航班入编号k的廊桥堆 
	}
	//同上~~~~~ 
	for(int i=1;i<=m2;i++){
		e2.push(i);
	}
	for(int i=1;i<=m2;i++){
		while(l2.size()&&a2[i].s>l2.top().t){
			e2.push(l2.top().id);
			l2.pop();
		}
		k=e2.top(),e2.pop();
		++c2[k],l2.push(node{a2[i].t,k});
	}
	for(int i=1;i<=n;i++){//前缀和 
		c1[i]+=c1[i-1];
	}
	for(int i=1;i<=n;i++){
		c2[i]+=c2[i-1];
	}
	int ans=0;
	for(int i=0;i<=n;i++){
		ans=max(ans,c1[i]+c2[n-i]);//
	}
	cout<<ans<<endl;
	return 0;
}

T2 考前原本想要复习区间dp结果忘了,就没了

#include<bits/stdc++.h>
#define cs const 
#define pb push_back

using namespace std;
typedef vector<int> vi;
typedef long long ll;
cs int mod=1e9+7;
int add(int a,int b){
	return a+b>=mod?a+b-mod:a+b;
}
int dec(int a,int b){
	return a-b<0?a-b+mod:a-b;
}
int mul(int a,int b){
	return 1ll*a*b%mod;
}

void Add(int &a,int b){
	a=add(a,b);
}

void Dec(int &a,int b){
	a=dec(a,b);
}

void Mul(int &a,int b){
	a=mul(a,b);
}

cs int N=505;
int n,k;
char S[N];
int dp[N][N][2];
int sm[N][N];
bool ec[N][N][2];
int nxt[N];


int main()
{
	cin>>n>>k;
	scanf("%s",S+1);
	for(int i=1;i<=n;i++){
		nxt[i]=n+1;
		for(int j=i;j<=n;j++){
			if(S[j]=='('||S[j]==')'){
				nxt[i]=j;//标记每一个字符后面的第一个括号出现的位置 
				break;
			}
		}
	}
	for(int len=2;len<=n;len++){//区间dp基本操作,枚举区间长度 
		for(int l=1;l<=n;l++){//枚举区间起点 
			int r=l+len-1;
			if(r>n){
				break;//判定 
			}
			int c=0;
			if((S[l]=='('||S[l]=='?')&&(S[r]==')'||S[r]=='?')){//考虑括号内的情况(&……%*……*) 
				if(r-l-1==0){//考虑() 
					Add(c,1);
				}else{//考虑(***) 和 (()) 
					Add(c,dp[l+1][r-1][1]);
					if(r-l-1<=k){
						if(nxt[l+1]>=r){
							Add(c,1);
						}
					}
				}
				int z=min(k,r-l-2);//枚举长度 
				for(int t=1;t<=z;t++){//(**())
					if(S[l+t]==')'||S[l+t]=='('){
						break;
					}
					Add(c,dp[l+t+1][r-1][1]);
				}
				for(int t=1;t<=z;t++){//(()***)//内括号 
					if(S[r-t]==')'||S[r-t]=='('){
						break;
					}
					Add(c,dp[l+1][r-t-1][1]);
				}
			}
			dp[l][r][0]=c;//(())的情况 处理完括号内括号的情况 ??? 
			for(int i=l+1;i<r;i++){// 接着做括号里有*又有括号的情况 ??? 
				int p=min(r,nxt[i+1]);//枚举边界 ??? 
				p=min(p,i+k+1);
				Add(c,mul(dp[l][i][0],dec(sm[i+1][r],sm[p+1][r])));//后缀和+乘法原理 ??? 
			}
			dp[l][r][1]=c;
			sm[l][r]=add(c,sm[l+1][r]);//后缀合 
		}
	}
	cout<<dp[1][n][1]<<'\n';///输出 
	return 0;
}

T3 先咕着

 

上一篇:正交投影、格拉姆施密特正交


下一篇:算法提高 (一)