zoukankan      html  css  js  c++  java
  • 动态规划-数正方形(详解)

    描述:

    晓萌有一个N×N的的棋盘,中间有N*N个正方形的1×1的格子,他随机在棋盘上撒上一些棋子(假设全部正好落在各个格子里)。他希望知道,当前的棋盘上有多少个不包含棋子的,由至少四个1×1的格子组成的正方形(正方形之间可以有重叠的部分)。

    输入第1行为棋盘的边长N,第2行-第N+1组成一个每行有N个数字的棋盘,其中数字0表示这个格子内有棋子,1表示这个格子内没有棋子。(2≤N≤250)

    输出包括多行,每行包括两个用空格分隔的数字,分别表示可以找到的正方形的边长和这种边长的正方形的个数。

    样例输入

    6
    101111
    001111
    111111
    001111
    101101
    111001

    样例输出

    2 10         //2*2的正方形有10个
    3 4          //3*3的正方形有4个
    4 1         //4*4的正方形有1个

    分析:

    显然这是个动态规划,若用暴力搜索,会在大数组上超时,所以需要每次保存上次的状态

    先来分析下2*2的正方形,如下图:

    从上图可以看出,当在第s[i][j]数组上,且这个数组值为1(有棋子),那它会与之前地s[i-1][j-1]、s[i-1][j]、s[i][j-1]有关,若这3个任意一个都不满足(为0)的话,那么s[i][j]就只能是个1*1正方形

    再来深入分析,3*3的正方形,如下图:

     从上图可以看出,要想第s[i][j]数组上构成一个大于等于3*3的正方形,必须s[i-1][j-1]、s[i-1][j]、s[i][j-1]都至少是个2*2的正方形,比如上图(3,3), 不然就会像上图(2,2)那样

    从这里我们可以看出s[i][j]非0情况下, 会等于 这3个数组(s[i-1][j-1]、s[i-1][j]、s[i][j-1])的最小值+1

    最后再分析一个有0数组,就迎刃而解了:

     

    同样地对于一个n*n正方形(n>=2),必定满足(n-1)*(n-1)正方形、(n-2)*(n-2)正方形 ... ...

     代码如下:

    #include<stdio.h>
    int s[300][300]={0},tp[300]={0};
    int main()
    {
        int i,j,n,min=0,m=1,cnt;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        scanf("%1d",&s[i][j]);
        for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        {
            if(s[i][j]!=0)   //第s[i][j]数组上,且这个数组值为1(有棋子)
            {
            min=(s[i-1][j]>s[i-1][j-1])?s[i-1][j-1]:s[i-1][j];
            min=(s[i][j-1]>min)?min:s[i][j-1];
            s[i][j]=min+1;               //等于 这3个数组(s[i-1][j-1]、s[i-1][j]、s[i][j-1])的最小值+1
            for(cnt=2;cnt<=min+1;cnt++) //对于一个n*n正方形(n>=2),必定满足(n-1)*(n-1)正方形、(n-2)*(n-2)正方形 ... ...
            tp[cnt]++;
            }            
        }
        for(i=2;i<=n;i++)
        if(tp[i]!=0)
        {   
        if(m)
        {
         printf("%d %d",i,tp[i]);
         m=0;
        }
        else   
        printf("
    %d %d",i,tp[i]);
        }
        return 0;
    } 
  • 相关阅读:
    JavaScript设计模式
    AgileConfig-如何使用AgileConfig.Client读取配置
    Java8的Optional:如何干掉空指针?
    k8s之DNS服务器搭建
    如何根据角色批量激活SAP Fiori服务
    被自己以为的GZIP秀到了
    Kubernetes官方java客户端之二:序列化和反序列化问题
    java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
    Shiro运行原理?
    Shiro认证过程?
  • 原文地址:https://www.cnblogs.com/lifexy/p/7550159.html
Copyright © 2011-2022 走看看