본문 바로가기
PS/BOJ

백준 21757 / C++

by jaehoonChoi 2022. 8. 1.

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

 

21757번: 나누기

$N$개의 정수 수열 $A_1, A_2, \dots , A_N$이 주어진다. 수열을 각각이 연속된 네 부분으로 나누려고 한다. 단, 각 부분은 최소 하나의 수를 포함해야 한다. 또, 각 부분의 합은 모두 같아야 한다. 즉, 어

www.acmicpc.net

 

[ 풀이 ] 

dp[i][j]를 i번째 인덱스까지 j개로 분할하는 방법의 수라고 놓자.

상태전이 시켜보자. i번을 안쓰는 경우 그냥 dp[i+1][j]로 넘어간다. 

i번을 사용하는 경우 dp[i+1][j+1]로 넘어간다. 사용할 수 있는 경우는 문제조건에 따라 잘 체크하면 된다. 

그리고 매번 i번에서 i+1만 참조하므로 토글링으로 공간복잡도를 조금 줄여줄 수 있다. 

 

[ Code ] 

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll n, x, psum[100001], dp[2][4];

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> x;
		psum[i] = psum[i - 1] + x;
	}
	if (psum[n] % 4) {
		cout << 0 << '\n';
		return 0;
	}
	dp[0][0] = 1;
	ll s = psum[n] / 4;

	// dp[i][j]=dp[i-1][j]+(i번 사용이 가능하다면)dp[i-1][j-1]
	for (ll i = 1; i <= n; i++) {
		dp[i % 2][0] = 1;
		for (ll j = 1; j <= 3; j++) {
			dp[i % 2][j] = dp[(i - 1) % 2][j];
			if (psum[i] == j * s) dp[i % 2][j] += dp[(i - 1) % 2][j - 1];
		}
	}
	cout << dp[(n - 1) % 2][3] << '\n';
}

'PS > BOJ' 카테고리의 다른 글

백준 24518 / C++  (0) 2022.08.01
백준 21909 / C++  (0) 2022.08.01
백준 12899 / C++  (0) 2022.08.01
백준 15561 / C++ / 구간합 최댓값 쿼리 O(logN)에 처리하기  (0) 2022.08.01
백준 15560 / C++  (0) 2022.08.01

댓글