[BOJ]1509号:ファリンドロン分割(C+)[GoldI]
問題に答える
Problem
は、ある文字列をファリンドロンの集合に分割できる数を尋ねる最初の問題である.
間違えました.しかし、問題は、少なくともいくつかのファリンドロンで文字列を表すことができることです.
文字列が で分割されたファリンドロンの長さだけが、分割の回数を最小限に抑えることができる. 文字列Sのサブ文字列が空かどうかを確認するには、O(N 3)を入力します.
Memoizationを利用すると,時間的複雑度はO(N 2)である.キャッシュ[開始][終了]
S[start:end-1]にパリンドロンが存在するか否かを配列で格納する. あるsubstringはfallin dromであり、最後のインデックスがiの場合i+1から始まる
パリンドロン串を探す過程を繰り返す.この過程を繰り返す
数を数えて、最高価格を探します. Result
上のコードでは、ソルバにコメントが書かれていないためタイムアウトします.
Problem
間違えました.しかし、問題は、少なくともいくつかのファリンドロンで文字列を表すことができることです.
文字列が
ABACABA
の場合、答えは1です.Solution
Memoizationを利用すると,時間的複雑度はO(N 2)である.キャッシュ[開始][終了]
S[start:end-1]にパリンドロンが存在するか否かを配列で格納する.
パリンドロン串を探す過程を繰り返す.この過程を繰り返す
数を数えて、最高価格を探します.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
int cache[2501][2501];
int dp[2501];
string str;
// 문자열의 start ~ (end - 1) Palindrome Check
int isPalindrome(int start, int end){
int& ret = cache[start][end];
if(ret != -1) return ret;
int len = (end - start) / 2;
for(int i=0; i<len; i++){
if(str[start + i] != str[end - 1 - i])
return ret = 0;
}
return ret = 1;
}
// Palindrome의 집합으로 문자열을 표현하고 그 개수의 최솟값을 구한다.
int solve(int start){
int len = str.length();
int& ret = dp[start];
if(ret != -1) return ret;
if(start == len) return ret = 0;
int mins = 10000;
for(int i=start + 1; i<=len; i++)
if(isPalindrome(start, i)){
mins = min(mins, solve(i) + 1);
}
return ret = mins;
}
int main(){
char s[2501];
scanf("%s", s);
str = s;
memset(cache, -1, sizeof(cache));
memset(dp, -1, sizeof(dp));
int mins = solve(0);
printf("%d \n", mins);
}
Result
Reference
この問題について([BOJ]1509号:ファリンドロン分割(C+)[GoldI]), 我々は、より多くの情報をここで見つけました https://velog.io/@brol2/BOJ-1509번-팰린드롬-분할テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol