DP[何桁目まで]
string m5(string a) { string b = a; a = a + "00"; b = "00" + b; reverse(a.begin(), a.end()); reverse(b.begin(), b.end()); vector<char> v; const int size = b.size(); int c = 0; for (int i = 0; i < size; ++i) { int n = (a[i] == '1') + (b[i] == '1') + c; if (n == 0) { v.push_back('0'); c = 0; } else if (n == 1) { v.push_back('1'); c = 0; } else if (n == 2) { v.push_back('0'); c = 1; } else if (n == 3) { v.push_back('1'); c = 1; } } if (c) v.push_back('1'); reverse(v.begin(), v.end()); string ret; for (int i = 0; i < v.size(); ++i) { ret += v[i]; } return ret; } bool match(string a, int base, string b) { if (base + b.size() <= a.size()) { for (int i = 0; i < b.size(); ++i) { if (a[i + base] != b[i]) return false; } return true; } return false; } class CuttingBitString { public: int getmin(string S) { vector<string> v; v.push_back("1"); v.push_back("101"); while (v.back().size() <= 50) { v.push_back(m5(v.back())); } const int inf = 1 << 28; const int N = S.size() + 1; int dp[N]; fill(dp, dp + N, inf); dp[0] = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < v.size(); ++j) { if (match(S, i, v[j])) { dp[i + v[j].size()] = min(dp[i + v[j].size()], dp[i] + 1); } } } int ret = dp[N - 1]; return ret == inf ? -1 : ret; } };