본문 바로가기

백준/DP

백준 14517 - 팰린드롬 개수 구하기 (Large)

728x90
728x90

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

풀이

다음 테이블을 세운다.

 

dp(i, j) := i번째 문자부터 j번째 문자까지 해서 부분 수열을 구성했을 때 나올 수 있는 팰린드롬의 갯수

 

그러면 dp(i, i) = 1, dp(i, i + 1) = 2로 초기화를 할 수 있다. 이 때 입력으로 주어진 문자열 s에 대해 s[i] = s[i + 1]이면 대칭인 팰린드롬이 존재하는 것이므로 dp(i, i + 1) = 3이 된다.

 

그리고 부분 수열이 가질 수 있는 범위 gap마다 반복문을 돌면서 다음을 더하거나 빼면 된다.

 

시작점이 i이고 끝점이 j일 때...

 

dp(i + 1, j)에서 그대로 가져오는 경우 -> dp(i, j)에서 단순히 확장한 것으로 간주할 수 있다.

 

dp(i, j - 1)에서 그대로 가져오는 경우 -> dp(i, j)에서 단순히 확장한 것으로 간주할 수 있다.

 

두 경우를 더하면 dp(i + 1, j - 1)에서 중복으로 더한 부분이 발생하리란 것은 당연하다. 따라서 dp(i + 1, j - 1)을 빼서 중복을 제거해야 한다.

 

그리고 s[i] = s[j]이면 두 문자가 대칭이라는 소리다. 따라서 다음 그림을 따라 dp(i + 1, j - 1)에 해당하는 부분을 다시 더할 필요가 있다.

 

 

위 계산을 통해 dp(0, n - 1)까지 구하면 정답이 된다. 모듈러 연산에 각별히 유의하도록 하자.

 

전체 코드

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2,fma")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
 
#include "bits/stdc++.h"
#include "ext/rope"
 
using namespace std;
using namespace __gnu_cxx;
 
using ll = long long;
using pii = pair<intint>;
 
const int mod = 10007;
string s;
int dp[1000][1000];
int n;
 
void solve()
{
  cin >> s;
  n = s.size();
  for (int i = 0; i < n; i++) dp[i][i] = 1;
 
  for (int i = 0; i < n - 1; i++)
  {
    dp[i][i + 1= 2;
    if (s[i] == s[i + 1]) ++dp[i][i + 1];
  }
 
  for (int gap = 2; gap < n; gap++)
  {
    for (int i = 0; i + gap < n; i++)
    {
      int j = i + gap;
      int &cur = dp[i][j];
      cur += dp[i + 1][j];
      cur += dp[i][j - 1];
      cur -= dp[i + 1][j - 1];
      while (cur < 0) cur += mod;
      cur %= mod;
 
      if (s[i] == s[j]) cur += dp[i + 1][j - 1+ 1;
      cur %= mod;
    }
  }
  cout << dp[0][n - 1];
}
 
int main()
{
#ifdef LOCAL
  freopen("input.txt""r", stdin);
//  freopen("output.txt", "w", stdout);
#endif
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
 
  solve();
}
cs

제출 기록

728x90
728x90

'백준 > DP' 카테고리의 다른 글

백준 24457 - 카페인 중독  (0) 2022.08.25
백준 1103 - 게임  (0) 2022.08.07
[ICPC] 백준 23342 - Histogram  (0) 2022.07.14
백준 14437 - 준오는 심술쟁이!!  (0) 2022.07.12
[KOI] 백준 21759 - 두 개의 팀  (0) 2022.07.09