zoukankan      html  css  js  c++  java
  • UVa 10502【dp】

    uva 10502

    题意:给定01矩阵,求有多少个由1构成的矩阵。1本事也算一个矩阵。

      到最后还是想不出来。。。。。

      每次枚举两行,从第i行到第j行,k枚举矩阵的宽(column)。这样就相当于每次看看每列i到j行之间是否全是1,是就累加tot,不是就tot置零。比如现在i=1,j=3,前k=3列为:

         i=1   1 1 1

               1 1 1

         j=3   1 1 1

    这时相当于竖着的长条都是1,所以k=1时,sum[1]=3,(因为当j=2、1时,sum的值已经计算过了,到这里由于值为1再加一下就是3了,也可以看成类似求竖着的largest empty interval),tot++,ans+=tot;k=2时,sum[2]=3,tot++,ans+=tot...

    这样算出来此时状态下ans=1+2+3=6.(把话说明白好难)

    参考代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int MAXN = 107;
     6 int maps[MAXN][MAXN];
     7 int sum[MAXN];
     8 char s[MAXN];
     9 int row, col;
    10 
    11 int main()
    12 {
    13     while (scanf("%d", &row) == 1, row)
    14     {
    15         scanf("%d", &col);
    16         memset(sum, 0, sizeof(sum));
    17         for (int i = 1; i <= row; i++)
    18         {
    19             scanf("%s", s);
    20             for (int j = 0; j<col; j++) {
    21                 maps[i][j + 1] = s[j] - '0';
    22             }
    23         }
    24         int ans = 0;
    25         for (int i = 1; i <= row; i++)//从第i行开始
    26         {
    27             memset(sum, 0, sizeof(sum));//每次换i行时清空sum,因为第i行是基础,j行随它变动
    28             for (int j = i; j <= row; j++)//到第j行
    29             {
    30                 int tot = 0;
    31                 for (int k = 1; k <= col; k++)//依次枚举
    32                 {
    33                     sum[k] += maps[j][k];
    34                     if (sum[k] != j - i + 1) tot = 0;//如果连续长度不满足tot清零
    35                     else tot++;//否则累加
    36                     ans += tot;//记录结果
    37                 }
    38             }
    39         }
    40         cout << ans << endl;
    41     }
    42     return 0;
    43 }

    当然,也可以行列互换,看成第i列到第j列的长条。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int MAXN = 107;
     6 int maps[MAXN][MAXN];
     7 int sum[MAXN];
     8 char s[MAXN];
     9 int row, col;
    10 
    11 int main()
    12 {
    13     while (scanf("%d", &row) == 1, row)
    14     {
    15         scanf("%d", &col);
    16         memset(sum, 0, sizeof(sum));
    17         for (int i = 1; i <= row; i++)
    18         {
    19             scanf("%s", s);
    20             for (int j = 0; j<col; j++) {
    21                 maps[i][j + 1] = s[j] - '0';
    22             }
    23         }
    24         int ans = 0;
    25         for (int i = 1; i <= col; i++)
    26         {
    27             memset(sum, 0, sizeof(sum));
    28             for (int j = i; j <= col; j++)
    29             {
    30                 int tot = 0;
    31                 for (int k = 1; k <= row; k++)
    32                 {
    33                     sum[k] += maps[k][j];
    34                     if (sum[k] != j - i + 1) tot = 0;
    35                     else tot++;
    36                     ans += tot;
    37                 }
    38             }
    39         }
    40         cout << ans << endl;
    41     }
    42     return 0;
    43 }
    i、j看成列

    而且有一个非常有意思的性质,当矩阵是n*n且全是1时,答案就是前n个数的立方和。

  • 相关阅读:
    SiteMesh在项目中的配置
    javascript深入理解js闭包
    小tip: 使用CSS将图片转换成黑白(灰色、置灰)
    java程序员最不愿意看到的十件事
    Spring AOP AspectJ
    2万字Java并发编程面试题整理(含答案,建议收藏)
    85道Java微服务面试题整理(助力2020面试)
    10个很多人不知道的Redis使用技巧
    2020年大厂Java面试题(基础+框架+系统架构+分布式+实战)
    2020年薪30W的Java程序员都要求熟悉JVM与性能调优!
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7412723.html
Copyright © 2011-2022 走看看