프로그래밍/백준 알고리즘

백준 알고리즘 풀이 1915번 - 가장 큰 정사각형

good programmer 2019. 10. 15. 11:22

https://www.acmicpc.net/problem/1915

 

1915번: 가장 큰 정사각형

첫째 줄에 n, m(1 ≤ n, m ≤ 1,000)이 주어진다. 다음 n개의 줄에는 m개의 숫자로 배열이 주어진다.

www.acmicpc.net

 

1915번

- 다이나믹 프로그래밍

 

- 알고리즘 -

1. 전체 맵의 오른쪽 아래를 기준으로 정사각형의 왼쪽 위라고 가정한다.

2. counts[][] 배열을 만들어서 그 지점을 좌측 상단으로 하는 가장 큰 정사각형이라고 정의한다.

3. counts[a][b] = min(counts[a+1][b],counts[a][b+1],counts[a+1][b+1])+1

-시간 복잡도-

맵의 총크기 : O(n) * O(n)

각 경우당 4번씩 탐색. 따라서 총 시간 복잡도 = 4 * O(n) * O(n)

- 예외 조건 -

1. counts[a][b]에서 a==dimY 이나 b==dimX 라면 counts[a][b]=1.

 

dp라고 인식하고, counts[a][b] = min(counts[a+1][b],counts[a][b+1],counts[a+1][b+1])+1 이 부분을 생각하는 것이 조금 복잡했다. 저것만 생각할 수 있다면 어렵지 않게 풀 수 있던 문제. 

-소스 코드-

#include <iostream>
#include <cstring>

using namespace std;

int map[1001][1001];
int counts[1001][1001]={0,};
int dimX,dimY;

int main()
{
	int ans=0;
	cin>>dimY>>dimX;
	for(int i=1;i<=dimY;i++){
		for(int j=1;j<=dimX;j++){
			scanf("%1d",&map[i][j]);
		}
	}
	for(int y=dimY;y>=1;y--){
		for(int x=dimX;x>=1;x--){
			if(map[y][x]==1){
				int minimum=1001;
				if(x==dimX || y==dimY){
					minimum=0;
				}
				else{
					for(int i=0;i<=1;i++){
						for(int j=0;j<=1;j++){
							if(i==0 && j==0) continue;
							if(minimum>counts[y+i][x+j]) minimum=counts[y+i][x+j];
						}
					}
				}
				counts[y][x]=minimum+1;
				if(minimum>=ans) ans=minimum+1;
			}
		}
	}
	cout<<ans*ans;
}

 

 

틀린 내용이나 지적 언제나 환영입니다.

도움이 되었다면 하트 한번씩 눌러주세요:)