• 【Hihocoder1634】Puzzle Game(DP)


    题意:有一个n*m的矩阵,每个矩阵里有一个数字a[i][j]。现在要求将其中一个格子的值改为p,使得修改后矩阵的最大子矩阵和最小,求这个最小值

    n,m<=150,abs(a[i][j])<=1e3

    思路:学习cf,也把这种题叫DP了……

    考虑如何快速求出修改后最大子矩阵的值

    最大子矩阵有一个O(n^3)的写法:枚举所处的两行或两列,剩下的就当做最大子串做

    用这样的方法预处理出上下左右四个方向的最大子矩阵之后,枚举任意一个原最大子矩阵中每个点是否修改

    如果有多个最大子矩阵除非枚举到重叠部分否则答案不会改变

    枚举后的答案即为原最大子矩阵的值修改后的值与上下左右四个方向的max取max

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<bitset>
      7 typedef long long ll;
      8 using namespace std;
      9 #define N   160
     10 #define oo  10000000
     11 #define MOD 100000073
     12 
     13 int s[N][N],a[N][N],U[N],D[N],L[N],R[N];
     14 
     15 int calc(int x1,int y1,int x2,int y2)
     16 {
     17     return s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];
     18 }
     19 
     20 int main()
     21 { 
     22     //freopen("hihocoder1634.in","r",stdin);
     23     //freopen("hihocoder1634.out","w",stdout); 
     24     int n,m,p;
     25     while(scanf("%d%d%d",&n,&m,&p)!=EOF)
     26     {
     27         for(int i=1;i<=n;i++)
     28          for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
     29         memset(s,0,sizeof(s));
     30         for(int i=0;i<=n+1;i++) U[i]=D[i]=-oo;
     31         for(int i=0;i<=m+1;i++) L[i]=R[i]=-oo;
     32         for(int i=1;i<=n;i++)
     33          for(int j=1;j<=m;j++) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
     34         int ans=-oo;
     35         for(int i=1;i<=n;i++)
     36         { 
     37             int tmp=-oo; 
     38              for(int j=1;j<=i;j++)
     39             {
     40                  int t=0;
     41                  for(int k=1;k<=m;k++) 
     42                  {
     43                      t+=calc(j,k,i,k);
     44                      tmp=max(tmp,t); 
     45                      if(t<0) t=0;
     46                  } 
     47              }
     48              U[i]=max(U[i-1],tmp);
     49              ans=max(ans,U[i]);
     50         }
     51         
     52         for(int i=n;i>=1;i--)
     53         { 
     54             int tmp=-oo; 
     55              for(int j=i;j<=n;j++)
     56             {
     57                  int t=0;
     58                  for(int k=1;k<=m;k++) 
     59                  {
     60                      t+=calc(i,k,j,k);
     61                      tmp=max(tmp,t); 
     62                      if(t<0) t=0;
     63                  } 
     64              }
     65              D[i]=max(D[i+1],tmp);
     66         }
     67         
     68         for(int i=1;i<=m;i++)
     69         {
     70             int tmp=-oo;
     71             for(int j=1;j<=i;j++)
     72             {
     73                 int t=0;
     74                 for(int k=1;k<=n;k++)
     75                 {
     76                     t+=calc(k,j,k,i);
     77                     tmp=max(tmp,t);
     78                     if(t<0) t=0;
     79                 }
     80             }
     81             L[i]=max(L[i-1],tmp);
     82         }
     83         
     84         for(int i=m;i>=1;i--)
     85         {
     86             int tmp=-oo;
     87             for(int j=m;j>=i;j--)
     88             {
     89                 int t=0;
     90                 for(int k=1;k<=n;k++)
     91                 {
     92                     t+=calc(k,i,k,j);
     93                     tmp=max(tmp,t);
     94                     if(t<0) t=0;
     95                 }
     96             }
     97             R[i]=max(R[i+1],tmp);
     98         }
     99         
    100         int sx=0,sy=0,ex=0,ey=0;
    101         for(int i=1;i<=n;i++)
    102          for(int j=i;j<=n;j++)
    103          {
    104              if(sx) break;
    105              int tmp=-oo;
    106              int t=0;
    107              int st=1;
    108              for(int k=1;k<=m;k++)
    109             {
    110                 t+=calc(i,k,j,k);
    111                 tmp=max(tmp,t);
    112                 if(tmp==ans)
    113                 {
    114                     sx=i; ex=j;
    115                     sy=st; ey=k;
    116                     break;
    117                 }
    118                 if(t<0)
    119                 {
    120                     t=0;
    121                     st=k+1;
    122                 }
    123             }    
    124         } 
    125         //printf("ans=%d
    ",ans);
    126         //printf("%d %d %d %d
    ",sx,sy,ex,ey);            
    127         int cnt=ans; 
    128         for(int i=sx;i<=ex;i++)
    129          for(int j=sy;j<=ey;j++) cnt=min(cnt,max(ans-a[i][j]+p,max(max(max(U[i-1],D[i+1]),L[j-1]),R[j+1]))); 
    130         printf("%d
    ",cnt);
    131     }
    132     return 0;
    133 }
    134     
  • 相关阅读:
    memcached命令
    模块管理常规功能自己定义系统的设计与实现(14--模块图表分析的设计)
    [易飞]凭证设计扩展字段之内容-文字显示格式
    将替代ListView的RecyclerView 的使用(一)
    POJ 2049— Finding Nemo(三维BFS)10/200
    最好用的jquery列表拖动排列(由项目提取)
    编程算法
    java几个easy出错的小程序
    GoldenGate配置(三)之DDL复制配置
    aused by: org.apache.xmlbeans.SchemaTypeLoaderException: XML-BEANS compiled schema: Incompatible min
  • 原文地址:https://www.cnblogs.com/myx12345/p/9996115.html
Copyright © 2020-2023  润新知