题目连接:https://atcoder.jp/contests/agc040/tasks/agc040_b
大佬题解:https://blog.csdn.net/duanghaha/article/details/102892233
题意:有N个问题,每个问题可以由编号L~R之间的人完成,有两个集合S和T,将N个问题放入两个集合中,使得交集和最大
题解与证明
首先找到lmost,与rmin,当区间rmin与lmost在同一个集合中,此时答案为rmin-lmost+1+most_width(最大宽度)
当二者不再同一个集合中时,那么答案为 max((rmin-x+1)+(y-lmost+1))其中x为l[i],y为r[j]注意x与y不可以是同一个区间的左右边界。
现在已经确定了集合S中有lmost,所以,T中一定有rmin。。问题转换为一个数组,,两个参数,将这个数组划分为来年部分。使得两部分的和最大
#include<bits/stdc++.h> using namespace std; const int INF=1e9+7; const int N=1E5+7; int l[N],r[N]; int arr[N]; struct stu{ int a,b; bool friend operator <(const stu &x,const stu &y){ return x.a>y.a; } }s[N]; int main() { int n; cin>>n; int lmax=0,rmin=INF,width=0; for(int i=1;i<=n;i++){ cin>>l[i]>>r[i]; if(l[i]>=lmax) lmax=l[i]; if(r[i]<=rmin) rmin=r[i]; width=max(width,r[i]-l[i]+1); } int sum=max(rmin-lmax+1,0)+width; for(int i=1;i<=n;i++){ s[i].a=max(0,rmin-l[i]+1); s[i].b=max(0,r[i]-lmax+1); } sort(s+1,s+1+n); arr[n]=s[n].b; for(int i=n-1;i>=1;i--) arr[i]=min(arr[i+1],s[i].b); int ans=0; for(int i=1;i<=n-1;i++) ans=max(ans,s[i].a+arr[i+1]); cout<<max(ans,sum)<<endl; return 0; }
M - AB Substrings
记录一下以b开头的字符串的数目,记录一下以a结尾的字符串的数目,在记录以b开头a结尾的字符串的数目
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll aend=0,bhead=0,ab=0; int main() { int n; cin>>n; string s; ll ans=0; for(int i=1;i<=n;i++){ cin>>s; int x=s.size(); for(int j=0;j<x-1;j++){ if(s[j]==‘A‘&&s[j+1]==‘B‘) ans++; } if(s[0]==‘B‘&&s[x-1]==‘A‘) ab++; if(s[0]==‘B‘) bhead++; if(s[x-1]==‘A‘) aend++; } aend-=ab; bhead-=ab; if(aend==0&&bhead==0){ if(ab==0||ab==1) cout<<ans<<endl; else cout<<ans+ab-1<<endl; } else if(aend==0||bhead==0){ cout<<ans+ab<<endl; } else if(aend!=0&&bhead!=0){ cout<<ans+min(aend,bhead)+ab<<endl; } return 0; }