A:Equivalent Prefixes
给你两个长度为n的序列a、b,求一个最大k值使,i-k 中任意一个区间的最小值下标都相同
我们用单调栈处理每个元素作为最小值的左端点。
我们把下标放进栈中,比较的时候比较具体的值,维护一个值逐渐变大的单调栈。
若当前栈为空,则说明没有比当前值更小的元素,那么就从1开始。
其他就为 比当前值更小的元素下标+1
最后比较两个元素的左端点值是否相同就可。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <stack> 9 #include <vector> 10 #include <cctype> 11 #include <sstream> 12 using namespace std; 13 typedef long long ll; 14 const int inf=0x7fffffff; 15 const int N=100000+100; 16 const int M=5000+10; 17 const double PI=acos(-1.0); 18 int T,n; 19 int a[N],b[N]; 20 int A[N],B[N]; 21 void solve(int t[],int a[]) 22 { 23 stack<int>s; 24 for(int i=1;i<=n;i++) 25 { 26 while(s.size()&&a[s.top()]>a[i]) 27 s.pop(); 28 if(s.empty()) t[i]=1; 29 else t[i]=s.top()+1; 30 s.push(i); 31 } 32 } 33 int main() 34 { 35 while(scanf("%d",&n)!=EOF) 36 { 37 38 int ans=n+1; 39 for(int i=1;i<=n;i++) 40 scanf("%d",&a[i]); 41 for(int i=1;i<=n;i++) 42 scanf("%d",&b[i]); 43 solve(A,a); 44 solve(B,b); 45 for(int i=1;i<=n;i++) 46 if(A[i]!=B[i]) 47 { 48 ans=i; break; 49 } 50 printf("%d ",ans-1); 51 } 52 53 54 55 return 0; 56 }
当时暴力了一种写法也过了。
每加入一个元素,判断加入这个元素对原本序列的影响。
也就是说加入一个元素下标为i,有影响的是 前面的询问 [i-1,i] [i-2,i] [i-3,i].....
若 同一下标 a[x]和b[x]都大于当前元素 continue;
若 同一下标 a[x]和b[x]都小于当前元素 break;跳出这个循环,不用往前面看,前面的序列一定都满足条件
若 同一下标 a[x]和b[x] 一个大于当前元素,另一个小于当前元素 这个就不成立了。
这种情况在最坏的情况下是 O(n*n)
E:ABBA
题目当时没看懂,以为就是有n个ab和m个ba
应该要知道 什么都没有的情况为1的。 f[0][0]=1;
题目是说有一个长度为 2(n+m) 的字符串,其中有(n+m)个A,(n+m)个B
其中有n个AB字串,m个BA字串。我们要知道这个字串的定义是不一定连续的。
也就是说 前n个‘A’一定是AB的‘A’,前m个'B'一定是BA的‘B’
主要是dp还不太会,一会去补dp专题。
设f[i][j]为有 i个'A',j个‘B’ 的字串数量。
当 i<n 时 f[i+1][j]+=f[i][j] 我们可以往后放一个‘A’
当min(j,m)> i-n 也就是说 当前放的B的数量要大于 ‘A’多的数量 我们也可以往后面放一个‘A’
B同理可得:
1 for(int i=0;i<=n+m;i++) 2 for(int j=0;j<=n+m;j++) 3 { 4 if(i<n||min(j,m)>i-n) 5 { 6 f[i+1][j]+=f[i][j]; 7 f[i+1][j]%=mod; 8 } 9 if(j<m||min(i,n)>j-m) 10 { 11 f[i][j+1]+=f[i][j]; 12 f[i][j+1]%=mod; 13 } 14 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <stack> 9 #include <vector> 10 #include <cctype> 11 #include <sstream> 12 using namespace std; 13 typedef long long ll; 14 const int inf=0x7fffffff; 15 const int N=100000+100; 16 const int M=5000+10; 17 const int mod=1e9+7; 18 const double PI=acos(-1.0); 19 int n,m; 20 int f[2100][2100]; 21 int main() 22 { 23 while(scanf("%d %d",&n,&m)!=EOF) 24 { 25 for(int i=0;i<=n+m;i++) 26 for(int j=0;j<=n+m;j++) 27 f[i][j]=0; 28 f[0][0]=1; 29 for(int i=0;i<=n+m;i++) 30 for(int j=0;j<=n+m;j++) 31 { 32 if(i<n||min(j,m)>i-n) 33 { 34 f[i+1][j]+=f[i][j]; 35 f[i+1][j]%=mod; 36 } 37 if(j<m||min(i,n)>j-m) 38 { 39 f[i][j+1]+=f[i][j]; 40 f[i][j+1]%=mod; 41 } 42 } 43 printf("%d ",f[n+m][n+m]); 44 } 45 46 47 48 return 0; 49 }