zoukankan      html  css  js  c++  java
  • 牛客多校第一场

    A

    题意:给两个相同长度的数字串,求一个最大的p,使两个数字串都满足[1,p]中任何一个区间的最小值下标都相同,

    思路:对于两个数字串要求最大的p,可以想到这个p的左边的区间[1,x]也肯定满足,所以想到从左往右顺推,然后每次都新加一个数字,判断这个新的区间是否满足,就只需要判断这个数字左侧第一个比它小的数字位置是否相同,如果相同那么新加的这个数字可以,否则最长长度到此为止。判断每个数字左侧第一个比它小的位置可以用单调栈维护一个递增的序列来求,对于每次入栈的数字,栈中上一个元素的位置就是第一个比它小的位置。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=1e5+10;
    int a[maxn],b[maxn];
    int st[maxn];
    int lmin1[maxn],lmin2[maxn];
    
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            for(int i=1; i<=n; i++)
                scanf("%d",&a[i]);
            for(int i=1; i<=n; i++)
                scanf("%d",&b[i]);
            int l,r;
            l=1;
            r=0;
            for(int i=1; i<=n; i++)
            {
                while(l<=r&&a[st[r]]>=a[i])
                    r--;
                lmin1[i]=st[r];
                st[++r]=i;
            }
            l=1;
            r=0;
            for(int i=1; i<=n; i++)
            {
                while(l<=r&&b[st[r]]>=b[i])
                    r--;
                lmin2[i]=st[r];
                st[++r]=i;
            }
            int ans=0;
            for(int i=1; i<=n; i++)
            {
                if(lmin1[i]==lmin2[i])
                    ans=i;
                else
                    break;
            }
            printf("%d
    ",ans);
        }
    }
    View Code

    E

    题意:求有多少种字符串满足含有n个AB的子序列和m个BA的子序列。

    思路:咋这么难想了QAQ,设状态转移方程f[i,j]表示:(在构成这个长度为n+m的字符串的过程中)前缀长度为i+j的字符串中有i个A和j个B的合法方案数有多少,合法方案就是可能满足条件的方案,可以想到不满足条件的方案就是前i+j中出现了大于n+j(j<=m)个A或者前i+j中出现了大于m+i(i<=n)个B,其余的都是合法方案,然后转移方程f[i][j]+=f[i-1][j]&&f[i][j]+=f[i][j-1]表示只能从前一个长度的字符串加个A或者加个B的方案数转移过来。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=1e3+10;
    const int mod=1e9+7;
    #define ll long long
    ll f[maxn*2][maxn*2];
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=0; i<=n; i++)
                f[i][0]=1;
            for(int i=0; i<=m; i++)
                f[0][i]=1;
            for(int i=1; i<=n+m; i++)
                for(int j=1; j<=n+m; j++)
                {
                    if(i<=(n+min(j,m))) f[i][j]=(f[i][j]+f[i-1][j])%mod;
                    if(j<=(m+min(i,n))) f[i][j]=(f[i][j]+f[i][j-1])%mod;
                }
            printf("%lld
    ",f[n+m][n+m]);
        }
    }
    View Code
  • 相关阅读:
    GUI 监听事件 (两个按钮,实现同一个监听)
    GUI 监听事件
    GUI 练习
    GUI 之表格布局
    GUI 之边界布局
    GUI 之流布局
    [转帖]Linux 下解压 rar 文件
    Linux 启动、停止、重启jar包脚本
    关于linux下,ls vi等命令失效的解决方法(配置下环境变量出现问题)
    超好用的UnixLinux 命令技巧 大神为你详细解读
  • 原文地址:https://www.cnblogs.com/dongdong25800/p/11219092.html
Copyright © 2011-2022 走看看