zoukankan      html  css  js  c++  java
  • poj 2029 get many persimmon trees

    题目大意:

    有一个01矩阵,求其所有a*b的子矩阵中总和最大的子矩阵的权值和

    思路:

    二维树状数组

    n2log2n

    虽然poj数据太弱了,二维前缀和就过了

    好多天以后发现二位前缀和比树状数组快。。。

    经过实验:一样快。。。

    附两种代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<vector>
     9 #include<set>
    10 #include<stack>
    11 #define inf 2147483611
    12 #define ll long long
    13 #define MAXN 510
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;
    18     char ch;ch=getchar();
    19     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    20     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    21     return x*f;
    22 }
    23 int map[MAXN][MAXN],x,y,s,t,n,ans;
    24 int main()
    25 {
    26     int a,b;
    27     while(scanf("%d",&n)&&n)
    28     {
    29         memset(map,0,sizeof(map));
    30         x=read(),y=read();
    31         for(int i=1;i<=n;i++)
    32         {
    33             a=read(),b=read();
    34             map[b][a]=1;
    35         }
    36         s=read(),t=read();
    37         ans=-1;
    38         for(int i=1;i<=y;i++)
    39             for(int j=1;j<=x;j++)
    40             {
    41                 map[i][j]+=map[i-1][j]+map[i][j-1]-map[i-1][j-1];
    42             } 
    43         for(int i=t;i<=y;i++)
    44             for(int j=s;j<=x;j++)
    45             {
    46                 ans=max(ans,map[i][j]-map[i-t][j]-map[i][j-s]+map[i-t][j-s]);
    47             } 
    48         printf("%d
    ",ans);
    49     }
    50 }
    二维前缀和
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<vector>
     9 #include<set>
    10 #include<stack>
    11 #define inf 2147483611
    12 #define ll long long
    13 #define MAXN 510
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;
    18     char ch;ch=getchar();
    19     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    20     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    21     return x*f;
    22 }
    23 int c[MAXN][MAXN],x,y,s,t,n,ans;
    24 int lowbit(int x) {return x&(-x);}
    25 void update(int a,int b)
    26 {
    27     for(int i=a;i<=y;i+=lowbit(i))
    28         for(int j=b;j<=x;j+=lowbit(j))
    29         {
    30             c[i][j]++;
    31         }
    32 }
    33 int sum(int a,int b)
    34 {
    35     int ans=0;
    36     for(int i=a;i>=1;i-=lowbit(i))
    37         for(int j=b;j>=1;j-=lowbit(j))
    38         {
    39             ans+=c[i][j];
    40         }
    41     return ans;
    42 }
    43 int main()
    44 {
    45     int a,b;
    46     while(scanf("%d",&n)&&n)
    47     {
    48         memset(c,0,sizeof(c));
    49         x=read(),y=read();
    50         for(int i=1;i<=n;i++)
    51         {
    52             a=read(),b=read();
    53             update(b,a);
    54         }
    55         s=read(),t=read();
    56         ans=-1;
    57         for(int i=t;i<=y;i++)
    58             for(int j=s;j<=x;j++)
    59             {
    60                 ans=max(ans,sum(i,j)-sum(i-t,j)-sum(i,j-s)+sum(i-t,j-s));
    61             } 
    62         printf("%d
    ",ans);
    63     }
    64 }
    二维树状数组
  • 相关阅读:
    二叉树前、中、后遍历
    程序员节宜冒泡
    HashMap源码分析
    Stack源码解析
    逆袭之旅DAY24.XIA.二重进阶、双色球
    逆袭之旅DAY24.XIA.数组练习
    LY.JAVA面向对象编程.内部类
    LY.JAVA面向对象编程.修饰符
    LY.JAVA面向对象编程.包的概述、导包
    XIA.人机猜拳
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7617076.html
Copyright © 2011-2022 走看看