天天看点

P2733 家的范围 Home on the Range-动态规划,矩形dp

农民约翰在一片边长是N (2 <= N <= 250)英里的正方形牧场上放牧他的奶牛。(因为一些原因,他的奶牛只在正方形的牧场上吃草。)遗憾的是,他的奶牛已经毁坏一些土地。( 一些1平方英里的正方形)

输出那些存在的正方形的边长和个数,一种一行。

矩阵dp

num[i]表示面积为i的矩阵的个数;

模板:f[i][j]表示以i,j为右下角所能扩展的最大矩阵大小由于f[i][j]是由f[i-1][j],f[i-1][j-1]和f[i][j-1]决定的,所以方程为f[i][j]=min(f[i-1][j],f[i-1][j-1]),f[i][j-1]);

因为每一个大的都包含一个小的,最后统计全部的个数:num[i-1]+=num[i]

https://www.luogu.org/problemnew/show/P2733

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
bool map[251][251];
int num[251*251];
int f[251][251];
char a[251][251];
int main()
{
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    for(int i=0;i<n;i++)
    f[i][0]=(a[i][0]=='1');
    for(int j=1;j<=n;j++)
    f[0][j]=(a[0][j]=='1');
    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++){
            if(a[i][j]=='1'){
                f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
            }
            num[f[i][j]]++;
        }
    }
    for(int i=n;i>0;i--){
        num[i-1]+=num[i];
    }
    for(int i=2;i<=n;i++){
        if(num[i]){
            cout<<i<<" "<<num[i]<<endl;
        }
    }
    return 0;
}