• 笔试强训未触及题目(个人向)


    1.DP22 最长回文子序列

    1.题目

    2.解析

    这是一个区间dp问题,我们让dp[i][j]表示在区间[i,j]内的最长子序列长度,如图:

    3.代码

    1. public class LongestArr {//DP22 最长回文子序列
    2. public static void main(String[] args) {
    3. Scanner in = new Scanner(System.in);
    4. char[] arr = in.next().toCharArray();
    5. //让dp[i][j]表示在区间i,j内的最长子序列长度
    6. //dp[i][j]=当arr[i]==arr[j]时为dp[i+1][j-1]+2;
    7. //当arr[i]!=arr[j]时因为arr[i]和arr[j]其一肯定
    8. //有一个不在子序列中,所以dp[i][j]=Math.max(dp[i+1][j],dp[i][j-1]);
    9. int n = arr.length;
    10. int[][] dp = new int[n][n];
    11. //初始化,当i=j时为1,i>j时为0(因为长度为负数不能算有字符串,i
    12. for (int i = n - 1; i >= 0; i--) {
    13. for (int j = i; j < n; j++) {
    14. if (j == i) {
    15. dp[i][j] = 1;
    16. } else {
    17. if (arr[i] == arr[j]) {
    18. dp[i][j] = dp[i + 1][j - 1] + 2;
    19. } else {
    20. dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
    21. }
    22. }
    23. }
    24. }
    25. System.out.print(dp[0][n - 1]);
    26. }
    27. }

    2.数组变换

    1.题目

    2.解析

    那么综上所述我们只要知道最大的数是否能和其他数匹配就行,但是问题来了,怎么知道它们是否匹配呢。我们可以先让最大数除以另一个想要与之匹配的数,若除不尽,则不能匹配,若除尽,则判断商是否为2的n次方。这里除尽除不尽用%小数来表示。那怎么判断是否为2的n次方呢,这里有三种方式,一种是暴力求法,让这个数无限/2,%2即可,第二种是lowbit算法,判断x-(x&-x)是否为0,第三种就是之前做过的判断1的位数的位运算方法,因为我们只需要判断是否只有1位1,所以,判断x&(x-1)是否为0即可。下文采用的是lowbit算法。

    3.代码

    1. public class demo2 {//数组变换
    2. public static void main(String[] args) {
    3. Scanner in = new Scanner(System.in);
    4. //取最大的数和其余的数做比较,看这个数能否变成这个最大的数
    5. //输入时判断最大数
    6. int n = in.nextInt();
    7. int max = 0;
    8. int[] arr = new int[n];
    9. for (int i = 0; i < n; i++) {
    10. int tem = in.nextInt();
    11. if (i == 0) {
    12. max = tem;
    13. } else max = Math.max(tem, max);
    14. arr[i] = tem;
    15. }
    16. for (int i = 0; i < n; i++) {
    17. //判断能否变为最大的数
    18. if (max % arr[i] == 0) {
    19. int s = max / arr[i];
    20. if (s - (s & -s) != 0) {
    21. System.out.print("NO");
    22. return;
    23. }
    24. } else {
    25. System.out.print("NO");
    26. return;
    27. }
    28. }
    29. System.out.print("YES");
    30. }
    31. }

    3.DP10 最大子矩阵

    1.题目


    2.解析

    在判断矩阵最大大小之前,我们肯定要枚举所有矩阵,如图:

    1. for(int x1=0;x1
    2. for(int y1=0;y1
    3. for(int x2=x1;x2
    4. for(int y2=y1;y2
    5. //这里写判断大小的一系列逻辑
    6. }
    7. }
    8. }

    我们要计算矩阵内部的和,有两种方法,一种是暴力解法,用两层for循环来一个一个加起来,但是这样时间复杂度就是O(n^2)加上外部循环就是 O(n^6)。所以我们用第二种方法,前缀和如图:

    那么如何使用呢?如图:

    最后比较最大值就行


    3.代码

    1. public static void main(String[] args) {
    2. Scanner in = new Scanner(System.in);
    3. int n=in.nextInt();
    4. //输入数据
    5. int[][] arr=new int[n][n];
    6. for(int i=0;i
    7. for(int j=0;j
    8. arr[i][j]=in.nextInt();
    9. }
    10. }
    11. //用二维dp计算前缀和
    12. //dp[i-1][j-1]表示(0,0)到(i,j)的前缀和大小
    13. //初始化
    14. int[][] dp=new int[n+1][n+1];
    15. for(int i=1;i<=n;i++) {
    16. for(int j=1;j<=n;j++) {
    17. dp[i][j]=dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1]
    18. +arr[i-1][j-1];
    19. }
    20. }
    21. //枚举每一块矩阵
    22. int max=-0x3f3f3f3f;
    23. for(int x1=0;x1
    24. for(int y1=0;y1
    25. for(int x2=x1;x2
    26. for(int y2=y1;y2
    27. int tem=dp[y2+1][x2+1]-dp[y2+1][x1]-
    28. dp[y1][x2+1]+dp[y1][x1];
    29. if(max
    30. max=tem;
    31. }
    32. }
    33. }
    34. }
    35. }
    36. System.out.print(max);
    37. }

  • 相关阅读:
    【MySQL】MySQL事务隔离机制与实现原理详解
    C++(Qt)软件调试---线程死锁调试(15)
    Java-IO流(常用类)
    百面深度学习-循环神经网络
    Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?
    C++入门 第二篇( 引用、内联函数、auto关键字、指针空值nullptr)
    Tomcat服务部署、优化及多实例实验(Nginx+Tomcat负载均衡、动静分离)
    VMware Workstation里面安装ubuntu20.04的流程
    第一个程序
    好心情精神心理平台:精神病人最害怕什么?
  • 原文地址:https://blog.csdn.net/HarryQUQ/article/details/138726721