본문 바로가기
PS/BOJ

백준 3037 / C++

by jaehoonChoi 2022. 8. 22.

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

 

3037번: 혼란

첫째 줄에 혼란도가 C이고 길이가 N인 수열의 개수를 1,000,000,007로 나눈 나머지를 출력한다.

www.acmicpc.net

 

[ 풀이 ] 

dp[i][j]를 1~i까지 혼란도가 j인 수열의 개수라고 정의하자.

1~i번 칸에서 수 i를 놓는 위치를 생각해보자. 

i를 k번 칸에 놓았다면, k+1칸~i번 칸에 의해 혼란도가 i-k개 증가한다.   

따라서 i를 k번 칸에 놓을 때 혼란도가 j가 되려면 k번칸을 제외한 1~i-1에서 혼란도가 j-(i-k)가 되어야 한다.

따라서 식은 dp[i][j]=sum(dp[i-1][j-i+k])이다. 식을 더 개선해보자. 

dp[i][j]와 dp[i][j-1] 차를 구하면, dp[i-1][j]-dp[i-1][j-i]가 됨을 알 수 있다.

따라서 dp[i][j]=dp[i][j-1]+dp[i-1][j]-dp[i-1][j-i]가 된다. 

식을 계산시 i와 i-1만 보므로 토글링으로 공간을 줄여주자. 

 

[ Code ] 

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll n, c, dp[2][10001];
const ll mod = 1e9 + 7;

int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> c;
	dp[0][0] = 1;
	for (int i = 1; i <= n; i++) {
		dp[i%2][0] = 1;
		for (int j = 1; j <= c; j++) {
			dp[i%2][j] = (dp[i%2][j-1]+dp[1-i%2][j]-(j>=i?dp[1-i%2][j-i]:0)+mod)%mod;
		}
	}
	cout << dp[n%2][c];
}

 

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

백준 23877 / C++  (0) 2022.08.23
백준 14958 / C++  (0) 2022.08.22
백준 1866 / C++  (0) 2022.08.18
백준 5463 / C++  (0) 2022.08.17
백준 1017 / C++  (0) 2022.08.17

댓글