• [2019牛客]第一场


    题目链接

    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 }
    View Code

    当时暴力了一种写法也过了。

    每加入一个元素,判断加入这个元素对原本序列的影响。

    也就是说加入一个元素下标为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 }
    View Code
  • 相关阅读:
    jsp 表单回显
    jquery ajax
    锋利的jquery 事件 动画
    锋利的jquery DOM操作
    锋利的jquery
    JavaScript闭包
    oracle
    日期转化
    二分查找
    linux 常用命令
  • 原文地址:https://www.cnblogs.com/Kaike/p/11249904.html
Copyright © 2020-2023  润新知