• 前缀和之最大加权矩形


    P1719 最大加权矩形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    这个题目有两种解法,一种是基于暴力枚举和二位维前缀和得到的答案

    二位前缀和的思路,我们使用二维前缀和来预处理,只有开四个for循环来枚举矩形的左起点和右下方的点。来求,时间复杂度达到10的8次方维230

    1. import java.io.BufferedReader;
    2. import java.io.IOException;
    3. import java.io.InputStreamReader;
    4. import java.io.PrintWriter;
    5. import java.math.BigInteger;
    6. import java.math.MathContext;
    7. import java.security.PublicKey;
    8. import java.sql.SQLIntegrityConstraintViolationException;
    9. import java.util.ArrayList;
    10. import java.util.Arrays;
    11. import java.util.Collections;
    12. import java.util.Comparator;
    13. import java.util.Iterator;
    14. import java.util.LinkedList;
    15. import java.util.Objects;
    16. import java.util.PriorityQueue;
    17. import java.util.Scanner;
    18. import java.util.TreeMap;
    19. import java.util.TreeSet;
    20. public class Main {
    21. public static void main(String[] args) throws NumberFormatException, IOException {
    22. Scanner sc=new Scanner(System.in);
    23. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    24. PrintWriter pw1=new PrintWriter(System.out);
    25. //String[] aStrings=br.readLine().split(" ");
    26. aa=sc.nextInt();
    27. bb=new int[aa+1][aa+1];
    28. pre=new int[aa+1][aa+1];
    29. int a;
    30. int b;
    31. for(a=1;a<=aa;a++) {
    32. for(b=1;b<=aa;b++) {
    33. bb[a][b]=sc.nextInt();
    34. }
    35. }
    36. for(a=1;a<=aa;a++) {
    37. for(b=1;b<=aa;b++) {
    38. pre[a][b]=pre[a-1][b]+pre[a][b-1]+bb[a][b]-pre[a-1][b-1];
    39. // System.out.println("A"+pre[a][b]);
    40. }
    41. }
    42. int c;
    43. int d;
    44. int answer=0;
    45. for(a=1;a<=aa;a++) {
    46. for(b=1;b<=aa;b++) {
    47. for(c=a;c<=aa;c++) {
    48. for(d=b;d<=aa;d++) {
    49. answer=Math.max(answer, pre[c][d]-pre[a-1][d]-pre[c][b-1]+pre[a-1][b-1]);
    50. }
    51. }
    52. }
    53. }
    54. System.out.println(answer);
    55. }
    56. public static int aa;
    57. public static int[][] bb;
    58. public static int[][] pre;
    59. }

    毫秒

    一种是dp加不规则的前缀和的答案

    我们首先来看一n*1的矩形来求最大加权矩形,不难发现这就是求最大子段之和。

    有状态转移方程d[e]=Math.max(d[e-1]+c, c);

    那么扩展到二位矩形怎么半,

    我们可以将n*n的矩形进行压缩,怎么压缩?

    举个例子

    3 3 3 3

    3 3 3 3

    1 2 3 4

    5 6 3 4

    这是4*4的矩形,我们从第二行第二列开始取到第四行第四列为止。

    是   3 3 3

           2 3 4

           6 3 4

    我们压缩,压缩为一行有11 9 11然后按照一维的矩形来做即可

    那么关键有了,怎么预处理压缩,使用到preaa[a][b]=preaa[a-1][b]+preaa[a][b];

    然后我们枚举上界和下界。之后枚举第几列,这样将压缩后的值直接按照最长子段来求即可

    1. import java.io.BufferedReader;
    2. import java.io.IOException;
    3. import java.io.InputStreamReader;
    4. import java.io.PrintWriter;
    5. import java.math.BigInteger;
    6. import java.math.MathContext;
    7. import java.security.PublicKey;
    8. import java.sql.SQLIntegrityConstraintViolationException;
    9. import java.util.ArrayList;
    10. import java.util.Arrays;
    11. import java.util.Collections;
    12. import java.util.Comparator;
    13. import java.util.Iterator;
    14. import java.util.LinkedList;
    15. import java.util.Objects;
    16. import java.util.PriorityQueue;
    17. import java.util.Scanner;
    18. import java.util.TreeMap;
    19. import java.util.TreeSet;
    20. public class Main {
    21. public static void main(String[] args) throws NumberFormatException, IOException {
    22. Scanner sc=new Scanner(System.in);
    23. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    24. PrintWriter pw1=new PrintWriter(System.out);
    25. //String[] aStrings=br.readLine().split(" ");
    26. aa=sc.nextInt();
    27. preaa=new int[aa+1][aa+1];
    28. int a;
    29. int b;
    30. for(a=1;a<=aa;a++) {
    31. for(b=1;b<=aa;b++) {
    32. preaa[a][b]=sc.nextInt();
    33. preaa[a][b]=preaa[a-1][b]+preaa[a][b]//按列预处理
    34. }
    35. }
    36. int answer=0;
    37. for(a=1;a<=aa;a++) {//枚举列的上界
    38. for(b=a;b<=aa;b++) {//枚举列的的下界
    39. int c=0;//记录压缩后的序列的每个值
    40. int[] d=new int[aa+1];
    41. for(int e=1;e<=aa;e++) {
    42. c=preaa[b][e]-preaa[a-1][e];
    43. d[e]=Math.max(d[e-1]+c, c);//求出前n个连续数值的的最长数值和
    44. answer=Math.max(answer, d[e]);//取最大值
    45. }
    46. }
    47. }
    48. System.out.println(answer);
    49. }
    50. public static int aa;
    51. public static int[][] preaa;
    52. }

  • 相关阅读:
    正则表达式基础知识
    《微信小程序开发从入门到实战》学习二十五
    write tcp 127.0.0.1:53226->127.0.0.1:6379: use of closed network connection
    Docker部署gitlab_ce(避坑版---社区版)
    20231019 filezilla 配置 Windows与Ubuntu文件传输
    Spring中有哪几种方法获取HttpSession对象
    学习Uni-app开发小程序Day5
    文举论金:非农到来!黄金原油全面走势分析策略独家指导
    [无监督学习] 14.详细图解k-means 算法
    访问者模式
  • 原文地址:https://blog.csdn.net/m0_73862548/article/details/133893520