括号序列, 避嫌抢劫-拼多多笔试题

括号序列-拼多多笔试题

一个合法的圆括号表达式满足以下条件:

  1. “”空字符串被认为是合法的。
  2. 如果字符串“X”与“Y”是合法的,则“XY”也被认为是合法的。
  3. 如果字符串“X”是合法的,则“(X)”也是合法的。

例如,“”,“()”,“()()”,“(())”这些都是合法的。

现在给出两个不保证合法的由圆括号组成的字符串,你需要交错这两个圆括号序列(在组成的新字符串中,每个初始字符串都保持原来的顺序)得到一个新的合法的圆括号表达式(不同的交错方式可能得到相同的表达式,这种情况分开计数),求共有多少结果合法的交错方式(无法得到合法的圆括号表达式则输出0),输出结果对\(10^9+7\)取模后的值。

输入格式

输入共两行,每行包含一个由“(”和“)”组成的字符串,长度不超过2500。

输出格式

输出为一个数字,表示合法的交错方式数量对\(10^9+7\)取模后的值。

输入样例:

(()
())

输出样例:

19

考点:动态规划+前缀和+判断括号合法

dfs暴力只能通过三个样例。

import java.util.*;
public class Main {
    static int[] preSum(char[] s) {
        int[] sum = new int[s.length+1];
        for(int i=0; i < s.length; i++) {
            if(s[i] == '(')
                sum[i+1] = sum[i] + 1;
            else
                sum[i+1] = sum[i] - 1;
        }
        return sum;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        char[] s1 = sc.next().toCharArray();
        char[] s2 = sc.next().toCharArray();
        int[] sum1 = preSum(s1), sum2 = preSum(s2);
        int mod = 1000000007;
        int n = s1.length, m = s2.length;
        // System.out.println(Arrays.toString(sum1));
        // System.out.println(Arrays.toString(sum2));
        if(sum1[n] + sum2[m] != 0)
            System.out.println("0");
        else {
            int[][] f = new int[n+1][m+1];
            for(int i=0; i <= n; i++) {
                for(int j=0; j <= m; j++) {
                    if(i == 0 && j == 0) f[i][j] = 1;
                    else {
                        if(sum1[i] + sum2[j] >= 0) {
                            if(i > 0) f[i][j] += f[i-1][j];
                            if(j > 0) f[i][j] += f[i][j-1];
                            f[i][j] %= mod; 
                        }
                    }    
                }
            }
            // System.out.println(Arrays.deepToString(f));
            System.out.println(f[s1.length][s2.length]);
        }
        
    }
}

避嫌抢劫-拼多多笔试题

小镇沿街分布(可以理解为都在数轴上),有n家银行(位置以数轴的坐标表示,金额表示可以被抢走的金额)。

两个绑匪试图分别抢劫一个银行,为了让警方多奔波他们商定选择的两个银行距离不小于d。

请问,符合约定的情况下他们能抢到的总金额最大是多少。

输入格式

输入包含 n+1 行。

第一行包含两个整数 n 和 d,分别表示银行的数量和约定的距离。

接下来 n 行,每行包含两个整数 a 和 b ,分别表示坐标和金额。

输出格式

输出一个数字表示可以获得的最大金额。

数据范围

1 <= n <= \(2 \times 10^5\),

1 <= d, a, b <= \(10^8\)

注意:数据中保证至少存在两个银行之间的距离不小于 d。

输入样例:

6 3
1 1
3 5
4 8
6 4
10 3
11 2

输出样例:

11

考点:双指针算法

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), d = sc.nextInt();
        int[][] a = new int[n][2];
        for(int i=0; i < n; i++) {
            a[i][0] = sc.nextInt(); 
            a[i][1] = sc.nextInt();
        }
        Arrays.sort(a, (o1, o2)->o1[0]-o2[0]);
        int[] maxn = new int[n];
        for(int i=n-1; i >= 0; i--) {
            if(i == n-1) maxn[i] = a[i][1];
            else maxn[i] = Math.max(maxn[i+1], a[i][1]);
        }
        int res = 0, j = 0;
        for(int i=1; i < n; i++) {
            if(a[i][0] - a[j][0] < d) continue;
            else {
                int t = maxn[i] + a[j][1];
                if(res < t) res = t;
                j++; i--;
            }
        }
        System.out.println(res);
    }
}
posted @ 2020-05-28 21:23  li修远  阅读(235)  评论(0编辑  收藏  举报