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个数的立方和。

  • 相关阅读:
    Sql inner join
    转:MySQL 的show processlist
    session cookie
    集群和分布式
    设计模式
    Web性能优化——缓存
    关于 java 里面的路径
    1分钟看懂log4j 配置自己想要的日志信息
    spring @bean 的理解
    如何用iptables实现NAT(转)
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7412723.html
Copyright © 2011-2022 走看看