zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练1

    Equivalent Prefixes

    这个是一个用单调栈的题目,至于为什么可以用单调栈?

    把两个数组同时跑单调栈,如果每次进栈最多一个,当然在这个进栈之前肯定会有数出栈,

    如果存在一个数进栈了,然后这个时候判断一下进栈的这个数的位置是不是相同,如果不相同就说明肯定是不对的。

    为什么说这个时候只要考虑这个栈内的位置呢?

    首先,这个最小值之前的数肯定是不要考虑的,因为当前的栈底就是目前位置最小的了,之后的数和之前的数RMQ函数返回的函数值肯定是这个栈底。

    然后就是考虑栈内元素,这个应该很好想了。

    #include <cstdio>//描述中的“如果找到,就说“X,let’s fly”(此处,X为开始时间)…"
    #include <cstdlib>//和Output中的 “X, let's fly”
    #include <cstring>//里的“ ’ ”和 “ ' ” 不是一个符号,别复制错了!!!
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <string>
    #include <stack>
    #include <iostream>
    #include <map>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 1e5 + 10;
    typedef long long ll;
    int queue_mina[maxn];
    int queue_minb[maxn];
    int a[maxn], b[maxn];
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            bool flag = 1;
            int ans = n;
            for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
            for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
            int f1 = 1, t1 = 0;
            int f2 = 1, t2 = 0;
            int r = 1;
            while(r<=n)
            {
                while (f1 <= t1 && a[r] < a[queue_mina[t1]]) t1--;
                queue_mina[++t1] = r;
                while (f2 <= t2 && b[r] < b[queue_minb[t2]]) t2--;
                queue_minb[++t2] = r;
                //printf("t1=%d t2=%d queue_mina[%d]=%d queue_minb[%d]=%d
    ", t1, t2, t1, queue_mina[t1], t2, queue_minb[t2]);
                if (t1 != t2)
                {
                    flag = 0;
                    ans = r - 1;
                    break;
                }
                r++;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    A

     ABBA

    这个题目是一个dp,现在看完题解之后感觉还比较好想,但是这个条件的判断我觉得还是比较难的。

    就是判断哪一种一定不是答案

    下面有两种写法,理解了任意一种另一种都可以很快的写出来

        if(i-j>n||j-i>m)//为什么这么写就是对的呢?
                        //因为i代表的是A的数量,j代表的是B的数量,如果A-B的数量大于n,就说明前面至少有n+1个A,这个B的数肯定
                        //有一部分在后面,所以这样的话AB的数量肯定>n,这样就不对了,后面的j-i>m 同理可得。
                        //这里可以筛出一部分肯定不对的,那么为什么满足这个就肯定是正确的呢。
                        //这个可以这么理解,这个if条件句把一定不对的筛出去了,如果后面有不合理的状态放到了dp数组里面
                        //最后一直往后走放A,B前面不合理的状态还是会被筛出去的
                    {
                        dp[i][j] = 0;
                        continue;
                    }

    这个是一种dp转移 dp[x][y]表示选了x个A,y个B的方案数

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #include <vector>
    #include <map>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 1e5 + 10;
    typedef long long ll;
    const int mod = 1e9 + 7;
    ll dp[4400][4400];
    
    int main()
    {
        int n, m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=0;i<=n+m;i++)
            {
                for(int j=0;j<=n+m;j++)
                {
                    dp[i][j] = 0;
                }
            }
            for(int i=0;i<=(n+m);i++)
            {
                for(int j=0;j<=(n+m);j++)
                {
                    if(i-j>n||j-i>m)//为什么这么写就是对的呢?
                        //因为i代表的是A的数量,j代表的是B的数量,如果A-B的数量大于n,就说明前面至少有n+1个A,这个B的数肯定
                        //有一部分在后面,所以这样的话AB的数量肯定>n,这样就不对了,后面的j-i>m 同理可得。
                        //这里可以筛出一部分肯定不对的,那么为什么满足这个就肯定是正确的呢。
                        //这个可以这么理解,这个if条件句把一定不对的筛出去了,如果后面有不合理的状态放到了dp数组里面
                        //最后一直往后走放A,B前面不合理的状态还是会被筛出去的
                    {
                        dp[i][j] = 0;
                        continue;
                    }
                    if (i == 0 || j == 0) dp[i][j] = 1;
                    else dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
                }
            }
            printf("%lld
    ", dp[n + m][n + m]);
        }
        return 0;
    }
    1

    这个是dp[x][y]表示前面x个位置选了y个B的方案数

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #include <vector>
    #include <map>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 1e5 + 10;
    typedef long long ll;
    const int mod = 1e9 + 7;
    ll dp[4400][4400];
     
    int main()
    {
        int n, m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=0;i<=2*(n+m);i++)
            {
                for(int j=0;j<=2*(n+m);j++)
                {
                    dp[i][j] = 0;
                }
            }
            dp[0][0] = 1;
            if (n != 0) dp[1][1] = 1;
            if (m != 0) dp[1][0] = 1;
            for(int i=1;i<=2*(n+m);i++)
            {
                for(int j=0;j<=i;j++)
                {
                    if(i-2*j>m||2*j-i>n)
                    {
                        dp[i][j] = 0;
                        continue;
                    }
                    if (j == 0) dp[i][j] = 1;
                    else dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1]) % mod;
                }
            }
            printf("%lld
    ", dp[2 * (n + m)][n + m]%mod);
        }
        return 0;
    }
    2
  • 相关阅读:
    10分钟教你Python+MySQL数据库操作
    10分钟教你用eclipse上传代码到GitHub
    分享几个有趣的程序代码(有些还是值得学习的哦)~
    10分钟教你生成超高逼格微信朋友圈
    1.maven中pom.xml文件中<exclusions>标签认不到问题
    2. springboot启动报错:Field userMapper in com.service.UserService required a bean of type 'com.dao.UserMapper' that could not be found.
    1. SpringBoot启动后,报异常:This application has no explicit mapping for /error, so you are seeing this as a fallback.
    9. 一个list拆分成多个list返回
    12. myeclipse遇到Initializing java tooling(1%)终极解决办法
    42. oracle通过两张表的一个字段对应,update其中一张表的某个字段
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11246775.html
Copyright © 2011-2022 走看看