Mercurial > lbo > hg > ccplay
changeset 19:3a4bc31d0ffe
Minimum palindrome cuts
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 04 Apr 2023 22:11:01 +0200 |
parents | c875da0d9fdb |
children | ecc574aa2021 |
files | dynprog.cc |
diffstat | 1 files changed, 47 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/dynprog.cc Mon Apr 03 22:46:24 2023 +0200 +++ b/dynprog.cc Tue Apr 04 22:11:01 2023 +0200 @@ -402,6 +402,51 @@ return 0; } +template<typename It> requires random_access_iterator<It> +bool is_palindrome(It begin, It end) { + const size_t s = end - begin; + for (size_t i = 0; i < s/2; i++) { + if (*(begin+i) != *(begin + (s-i-1))) + return false; + } + return true; +} + +// https://www.techiedelight.com/find-minimum-cuts-needed-palindromic-partition-string/ +template<typename T, typename R> requires range<R> && is_same_v<range_value_t<R>, T> && random_access_iterator<iterator_t<R>> +int minimum_palindrome_cuts(const R& range, size_t from, size_t to, unordered_map<pair<size_t, size_t>, int, PairHash>& memo) { + if (is_palindrome(range.begin()+from, range.begin()+to)) + return 0; + if (to - from == 1) + return 0; + + auto key = make_pair(from, to); + auto entry = memo.find(key); + if (entry != memo.end()) + return entry->second; + + int mincuts = to-from; + size_t minix = to; + for (size_t i = from+1; i < to; i++) { + // Split at i. + int cuts1 = minimum_palindrome_cuts<T>(range, from, i, memo); + int cuts2 = minimum_palindrome_cuts<T>(range, i, to, memo); + int cuts = 1 + cuts1 + cuts2; + if (cuts < mincuts) { + mincuts = cuts; + minix = i; + } + } + memo.insert(make_pair(key, mincuts)); + return mincuts; +} + +int minimum_palindrome_cuts_main(char** argv) { + string s{argv[1]}; + unordered_map<pair<size_t, size_t>, int, PairHash> memo{}; + fmt::print("{}\n", timeit_f([&]() { return minimum_palindrome_cuts<char>(s, 0, s.size(), memo); })); +} + int lcss_main(void) { vector<int> a{1, 6, 2, -1, 3, 55, 2, 4, 23, 5, 6, 7, 8, 9, 10}; @@ -420,7 +465,7 @@ return 0; } -int main(void) { - three_partition_main(); +int main(int argc, char** argv) { + minimum_palindrome_cuts_main(argv); return 0; }