31778번: PPC 만들기
boj.ma
P와 C로만 이루어진 배열에서 위치변경 행위를 최대 K번 수행해서 부분문자열중 PPC 의 갯수를 최대화 하는 문제입니다.
PPC 부분 문자열의 정의가 "1≤𝑖<𝑗<𝑘≤𝑁 이고, 𝑆𝑖=𝑆𝑗= P, 𝑆𝑘= C인 (𝑖,𝑗,𝑘)의 개수"이기 때문에
P는 최대한 앞으로 C는 최대한 뒤로 옮겨줘 PPPPPP.....CCCCCC 형태가 되어야 PPC 부분문자열의 갯수를 최대화 할 수 있습니다.
그리디하게 위와 같은 형태로 만들었다고 쳐도, PPC 부분 문자열을 세어주는 과정이 남았습니다.
저는 PPC중 가운데 있는 P에 집중했습니다.
P를 만날때 마다 (내 앞의 P 갯수) * (내 뒤에 C갯수) 를 정답에 누적해주면 될것 같습니다.
하지만 이걸 모든 P를 만날때마다 하나하나 구해준다면 O(N^2)으로 시간초과입니다.
내 앞에 몇개 있는지, 내 뒤에 몇개 있는지 구하는것은 누적합을 통해 최적화가 가능합니다.
prefix_p, suffix_c 배열을 통해 O(N)에 전처리하고 P를 만날 때 마다
prefix_p[i - 1] * suffix_c[i] 를 정답에 누적해주면 전체 시간복잡도 O(N)으로 해결 가능합니다.
코드(c++)
#include <bits/stdc++.h>
#define endl "\n"
#define NM 100101
#define MAX 1010100
#define BIAS 1048576
#define MOD 1000000007
#define X first
#define Y second
#define INF 1000000000
#define FOR(i) for(int _=0;_<(i);_++)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(v) v.begin(), v.end()
#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
using namespace std;
int main() {
fastio
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
int n, k;
cin >> n >> k ;
vector<char> s(n + 2);
s[0] = s[n + 1] = 'X';
for (int i = 1 ; i <= n; i++) cin >> s[i];
int l = 0, r = n + 1;
while (l < r && k){ // P는 최대한 앞으로 두고 C는 최대한 뒤로 두기
while (l < n && s[l] != 'C') l++;
while (r >= 0 && s[r] != 'P') r--;
if (l >= r) break;
k--;
swap(s[l], s[r]);
}
// 누적합
vector<ll> prefix_p(n + 1), suffix_c(n + 2);
for (int i = 1; i <= n; i++){
prefix_p[i] = prefix_p[i - 1] + (s[i] == 'P');
}
for (int i = n; i >= 1; i--){
suffix_c[i] = suffix_c[i + 1] + (s[i] == 'C');
}
ll ans = 0;
for (int i = 1; i <= n; i++){
if (s[i] == 'P'){ // P를 만날 때마다
ans += prefix_p[i - 1] * suffix_c[i]; // 내 앞에 P 갯수 * 내 뒤에 C갯수
}
}
cout << ans << endl;
return 0;
}
인덱스 실수로 고생좀 했습니다.
그리고 prefix_p 배열을 굳이 만들지 말고 문자열을 순회하며 P의 갯수를 따로 누적해주는 것만으로도 해결할 수 있습니다.
'알고리즘 문제 풀이' 카테고리의 다른 글
백준 31786 최고의 친구 (0) | 2024.05.09 |
---|---|
백준 31782 저체온증 (0) | 2024.05.02 |
백준 10719 Baekjoon Database Management System (0) | 2024.04.30 |
프로그래머스 트리 트리오 중간값 (0) | 2024.04.25 |
백준 24501 blobaww (0) | 2024.04.25 |